InspectorsImpl.cpp
Go to the documentation of this file.
1 // kate: replace-tabs off; indent-width 4; indent-mode
2 // vim: ts=4:sw=4:noexpandtab
3 /*
4 
5 Copyright (c) 2010--2012,
6 François Pomerleau and Stephane Magnenat, ASL, ETHZ, Switzerland
7 You can contact the authors at <f dot pomerleau at gmail dot com> and
8 <stephane at magnenat dot net>
9 
10 All rights reserved.
11 
12 Redistribution and use in source and binary forms, with or without
13 modification, are permitted provided that the following conditions are met:
14  * Redistributions of source code must retain the above copyright
15  notice, this list of conditions and the following disclaimer.
16  * Redistributions in binary form must reproduce the above copyright
17  notice, this list of conditions and the following disclaimer in the
18  documentation and/or other materials provided with the distribution.
19  * Neither the name of the <organization> nor the
20  names of its contributors may be used to endorse or promote products
21  derived from this software without specific prior written permission.
22 
23 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
24 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
25 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26 DISCLAIMED. IN NO EVENT SHALL ETH-ASL BE LIABLE FOR ANY
27 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
28 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
29 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
30 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 
34 */
35 
36 #include "InspectorsImpl.h"
37 
38 #include "PointMatcherPrivate.h"
39 #include "IOFunctions.h"
40 
41 #include <cassert>
42 #include <iostream>
43 #include <sstream>
44 #include <fstream>
45 #include <algorithm>
46 #include <boost/type_traits/is_same.hpp>
47 
48 using namespace std;
49 using namespace PointMatcherSupport;
50 
51 template<typename T>
53  Inspector(className,paramsDoc,params),
54  baseFileName(Parametrizable::get<string>("baseFileName")),
55  bDumpPerfOnExit(Parametrizable::get<bool>("dumpPerfOnExit")),
56  bDumpStats(Parametrizable::get<bool>("dumpStats"))
57 
58 {//FIXME: do we need that constructor?
59 }
60 
61 template<typename T>
63  Inspector("PerformanceInspector", PerformanceInspector::availableParameters(), params),
64  baseFileName(Parametrizable::get<string>("baseFileName")),
65  bDumpPerfOnExit(Parametrizable::get<bool>("dumpPerfOnExit")),
66  bDumpStats(Parametrizable::get<bool>("dumpStats"))
67 {}
68 
69 template<typename T>
71 {
72  if (!bDumpStats) return;
73 
74  HistogramMap::iterator it(stats.find(name));
75  if (it == stats.end()) {
76  LOG_INFO_STREAM("Adding new stat: " << name);
77  it = stats.insert(HistogramMap::value_type(name, Histogram(16, name, baseFileName, bDumpPerfOnExit))).first;
78  }
79  it->second.push_back(data);
80 }
81 
82 template<typename T>
84 {
85  // Note: this dump format will most probably change in the future
86  for (BOOST_AUTO(it, stats.begin()); it != stats.end(); ++it)
87  {
88  it->second.dumpStats(stream);
89  BOOST_AUTO(jt, it);
90  ++jt;
91  if (jt != stats.end())
92  stream << ", ";
93  }
94 }
95 
96 template<typename T>
98 {
99  for (BOOST_AUTO(it, stats.begin()); it != stats.end(); ++it)
100  {
101  it->second.dumpStatsHeader(stream);
102  BOOST_AUTO(jt, it);
103  ++jt;
104  if (jt != stats.end())
105  stream << ", ";
106  }
107 }
108 
111 
112 /*
113  // This code creates a header according to information from the datapoints
114  std::ofstream ofs(fileName.c_str());
115  size_t labelIndex(0);
116  size_t labelComponent(0);
117  const typename DataPoints::Labels labels(data.featureLabels);
118  for (int i = 0; i < features.rows(); ++i)
119  {
120  // display label for row
121  if (labelIndex <= labels.size())
122  {
123  const typename DataPoints::Label label(labels[labelIndex]);
124  ofs << label.text;
125  if (label.span > 1)
126  ofs << "_" << labelComponent;
127  ++labelComponent;
128  if (labelComponent >= label.span)
129  ++labelIndex;
130  }
131  else
132  {
133  ofs << "?";
134  }
135  ofs << " ";
136  }*/
137 template<typename T>
139  PerformanceInspector(className,paramsDoc,params),
140  streamIter(0),
141  bDumpIterationInfo(Parametrizable::get<bool>("dumpIterationInfo")),
142  bDumpDataLinks(Parametrizable::get<bool>("dumpDataLinks")),
143  bDumpReading(Parametrizable::get<bool>("dumpReading")),
144  bDumpReference(Parametrizable::get<bool>("dumpReference")),
145  bWriteBinary(Parametrizable::get<bool>("writeBinary"))
146 {
147 }
148 
149 template<typename T>
151  if (boost::is_same<double, T>::value) {
152  return "double";
153  } else {
154  return "float";
155  }
156 }
157 
158 template<typename T>
160 {
161  const Matrix& features(data.features);
162  //const Matrix& descriptors(data.descriptors);
163 
164  stream << "# vtk DataFile Version 3.0\n";
165  stream << "File created by libpointmatcher\n";
166  stream << (bWriteBinary ? "BINARY":"ASCII") << "\n";
167  stream << "DATASET POLYDATA\n";
168 
169  stream << "POINTS " << features.cols() << " " << getTypeName<T>() << "\n";
170 
171  if(features.rows() == 4)
172  {
173  writeVtkData(bWriteBinary, features.topLeftCorner(3, features.cols()).transpose(), stream) << "\n";
174  }
175  else
176  {
177  writeVtkData(bWriteBinary, features.transpose(), stream) << "\n";
178  }
179 
180  stream << "VERTICES " << features.cols() << " "<< features.cols() * 2 << "\n";
181  for (int i = 0; i < features.cols(); ++i){
182  if(bWriteBinary){
183  stream.write(reinterpret_cast<const char*>(&oneBigEndian), sizeof(int));
184  ConverterToAndFromBytes<int> converter(i);
185  if(!isBigEndian){
186  converter.swapBytes();
187  }
188  stream.write(converter.bytes, sizeof(int));
189  }else {
190  stream << "1 " << i << "\n";
191  }
192  }
193 
194 
195  // Save points
196  stream << "POINT_DATA " << features.cols() << "\n";
197 
198  // Loop through all descriptor and dispatch appropriate VTK tags
199  for(BOOST_AUTO(it, data.descriptorLabels.begin()); it != data.descriptorLabels.end(); it++)
200  {
201  // handle specific cases
202  if(it->text == "normals")
203  {
204  buildNormalStream(stream, "normals", data);
205  }
206  else if(it->text == "eigVectors")
207  {
208  buildTensorStream(stream, "eigVectors", data);
209  }
210  else if(it->text == "color")
211  {
212  buildColorStream(stream, "color", data);
213  }
214  // handle generic cases
215  else if(it->span == 1)
216  {
217  buildScalarStream(stream, it->text, data);
218  }
219  else if(it->span == 3 || it->span == 2)
220  {
221  buildVectorStream(stream, it->text, data);
222  }
223  else
224  {
225  LOG_WARNING_STREAM("Could not save label named " << it->text << " (dim=" << it->span << ").");
226  }
227  }
228 
229  // Loop through all time fields, split in high 32 bits and low 32 bits and export as two scalar
230  for(BOOST_AUTO(it, data.timeLabels.begin()); it != data.timeLabels.end(); it++)
231  {
232  buildTimeStream(stream, it->text, data);
233  }
234 
235 }
236 
237 template<typename T>
239 {
240  //const Matrix& features(data.features);
241  const Matrix& descriptors(data.descriptors.transpose());
242 
243  assert(descriptors.cols() >= 15);
244 
245  stream << "# vtk DataFile Version 3.0\n";
246  stream << "Triangle mesh\n";
247  stream << "ASCII\n";
248  stream << "DATASET POLYDATA\n";
249 
250  stream << "POINTS " << descriptors.rows() * 3 << " float\n"; // not optimal: points and edges are drawn several times!
251  for (int i = 0; i < descriptors.rows(); i++)
252  {
253  // TODO: use getDescriptorByName(nameTag) to access blocks
254  stream << descriptors.block(i, 3, 1, 3) << "\n";
255  stream << descriptors.block(i, 6, 1, 3) << "\n";
256  stream << descriptors.block(i, 9, 1, 3) << "\n";
257  }
258 
259  //TODO: add centroids...
260  /*
261  stream << features.transpose() << "\n";
262  */
263 
264  stream << "POLYGONS " << descriptors.rows() << " " << descriptors.rows() * 4 << "\n";
265  for (int i = 0; i < descriptors.rows(); i++)
266  {
267  stream << "3 " << (i*3) << " " << (i*3 + 1) << " " << (i*3 + 2) << "\n";
268  }
269 
270  stream << "CELL_DATA " << descriptors.rows() << "\n";
271 
272  stream << "NORMALS triangle_normals float\n";
273  stream << descriptors.block(0, 0, descriptors.rows(), 3) << "\n";
274 
275  // TODO: use descriptor labels, particularly to represent normals
276  //stream << "POINT_DATA " << descriptors.rows() << "\n";
277  //buildScalarStream(stream, "densities", data);
278  //buildNormalStream(stream, "normals", data);
279  //buildVectorStream(stream, "eigValues", data);
280  //buildTensorStream(stream, "eigVectors", data);
281  //buildVectorStream(stream, "observationDirections", data);
282 }
283 
284 // FIXME:rethink how we dump stuff (accumulate in a correctly-referenced table, and then dump?) and unify with previous
285 template<typename T>
287  const DataPoints& ref,
288  const DataPoints& reading,
289  const Matches& matches,
290  const OutlierWeights& featureOutlierWeights,
291  std::ostream& stream)
292 {
293 
294  const Matrix& refFeatures(ref.features);
295  const int refPtCount(refFeatures.cols());
296  //const int featDim(refFeatures.rows());
297  const Matrix& readingFeatures(reading.features);
298  const int readingPtCount(readingFeatures.cols());
299  const int totalPtCount(refPtCount+readingPtCount);
300 
301  stream << "# vtk DataFile Version 3.0\n";
302  stream << "comment\n";
303  stream << "ASCII\n";
304  stream << "DATASET POLYDATA\n";
305 
306  stream << "POINTS " << totalPtCount << " float\n";
307  if(refFeatures.rows() == 4)
308  {
309  // reference pt
310  stream << refFeatures.topLeftCorner(3, refFeatures.cols()).transpose() << "\n";
311  // reading pt
312  stream << readingFeatures.topLeftCorner(3, readingFeatures.cols()).transpose() << "\n";
313  }
314  else
315  {
316  // reference pt
317  stream << refFeatures.transpose() << "\n";
318  // reading pt
319  stream << readingFeatures.transpose() << "\n";
320  }
321  const int knn = matches.ids.rows();
322 
323  size_t matchCount = readingPtCount*knn;
324  for (int k = 0; k < knn; ++k)
325  {
326  for (int i = 0; i < readingPtCount; ++i)
327  {
328  if (matches.ids(k, i) == Matches::InvalidId){
329  matchCount --;
330  }
331  }
332  }
333 
334  stream << "LINES " << matchCount << " " << matchCount * 3 << "\n";
335  //int j = 0;
336  for (int k = 0; k < knn; k++) // knn
337  {
338  for (int i = 0; i < readingPtCount; ++i)
339  {
340  const auto id = matches.ids(k, i);
341  if (id != Matches::InvalidId){
342  stream << "2 " << refPtCount + i << " " << id << "\n";
343  }
344  }
345  }
346 
347  stream << "CELL_DATA " << matchCount << "\n";
348  stream << "SCALARS outlier float 1\n";
349  stream << "LOOKUP_TABLE default\n";
350  //stream << "LOOKUP_TABLE alphaOutlier\n";
351  for (int k = 0; k < knn; k++) // knn
352  {
353  for (int i = 0; i < readingPtCount; ++i) //nb pts
354  {
355  const auto id = matches.ids(k, i);
356  if (id != Matches::InvalidId){
357  stream << featureOutlierWeights(k, i) << "\n";
358  }
359  }
360  }
361 
362  //stream << "LOOKUP_TABLE alphaOutlier 2\n";
363  //stream << "1 0 0 0.5\n";
364  //stream << "0 1 0 1\n";
365 
366 }
367 
368 template<typename T>
370 {
371  ostream* stream(openStream(name));
372  dumpDataPoints(filteredReference, *stream);
373  closeStream(stream);
374 }
375 
376 template<typename T>
378 {
379  ostream* stream(openStream(name));
380  dumpMeshNodes(filteredReference, *stream);
381  closeStream(stream);
382 }
383 
384 template<typename T>
386  const size_t iterationNumber,
388  const DataPoints& filteredReference,
389  const DataPoints& reading,
390  const Matches& matches,
391  const OutlierWeights& outlierWeights,
392  const TransformationCheckers& transCheck)
393 {
394 
395  if (bDumpDataLinks){
396  ostream* streamLinks(openStream("link", iterationNumber));
397  dumpDataLinks(filteredReference, reading, matches, outlierWeights, *streamLinks);
398  closeStream(streamLinks);
399  }
400 
401  if (bDumpReading){
402  ostream* streamRead(openStream("reading", iterationNumber));
403  dumpDataPoints(reading, *streamRead);
404  closeStream(streamRead);
405  }
406 
407  if (bDumpReference){
408  ostream* streamRef(openStream("reference", iterationNumber));
409  dumpDataPoints(filteredReference, *streamRef);
410  closeStream(streamRef);
411  }
412 
413  if (!bDumpIterationInfo) return;
414 
415  // streamIter must be define by children
416  assert(streamIter);
417 
418  if(iterationNumber == 0)
419  {
420  //Build header
421  for(unsigned int j = 0; j < transCheck.size(); j++)
422  {
423  for(unsigned int i=0; i < transCheck[j]->getConditionVariableNames().size(); i++)
424  {
425  if (!(j == 0 && i == 0))
426  *streamIter << ", ";
427  *streamIter << transCheck[j]->getConditionVariableNames()[i] << ", ";
428  *streamIter << transCheck[j]->getLimitNames()[i];
429  }
430  }
431 
432  *streamIter << "\n";
433  }
434 
435 
436  for(unsigned int j = 0; j < transCheck.size(); j++)
437  {
438  for(unsigned int i=0; i < transCheck[j]->getConditionVariables().size(); i++)
439  {
440 
441  if (!(j == 0 && i == 0))
442  *streamIter << ", ";
443 
444  *streamIter << transCheck[j]->getConditionVariables()[i] << ", ";
445  *streamIter << transCheck[j]->getLimits()[i];
446  }
447  }
448 
449  *streamIter << "\n";
450 }
451 
452 template<typename T>
453 void InspectorsImpl<T>::AbstractVTKInspector::buildGenericAttributeStream(std::ostream& stream, const std::string& attribute, const std::string& nameTag, const DataPoints& cloud, const int forcedDim)
454 {
455  if (!cloud.descriptorExists(nameTag))
456  return;
457 
458  const BOOST_AUTO(desc, cloud.getDescriptorViewByName(nameTag));
459  assert(desc.rows() <= forcedDim);
460 
461  if(desc.rows() != 0)
462  {
463  if(attribute.compare("COLOR_SCALARS") == 0)
464  {
465  stream << attribute << " " << nameTag << " " << forcedDim << "\n";
466  if(bWriteBinary){
467  std::vector<unsigned char> buffer(forcedDim, 0);
468  for (int i = 0; i < desc.cols(); ++i){
469  for(int r=0; r < desc.rows(); ++r){
470  buffer[r] = static_cast<unsigned int>(desc(r, i) * static_cast<T>(255) + static_cast<T>(0.5)); // this is how libvtk implements it ( vtkScalarsToColors::ColorToUChar )
471  }
472  stream.write(reinterpret_cast<char *>(&buffer.front()), forcedDim);
473  }
474  }
475  else {
476  stream << padWithOnes(desc, forcedDim, desc.cols()).transpose();
477  }
478  }
479  else
480  {
481  stream << attribute << " " << nameTag << " " << getTypeName<T>() << "\n";
482  if(attribute.compare("SCALARS") == 0)
483  stream << "LOOKUP_TABLE default\n";
484 
485  writeVtkData(bWriteBinary, padWithZeros(desc, forcedDim, desc.cols()).transpose(), stream);
486  }
487  stream << "\n";
488  }
489 }
490 
491 template<typename T>
493  const std::string& name,
494  const DataPoints& cloud)
495 {
496  buildGenericAttributeStream(stream, "SCALARS", name, cloud, 1);
497 }
498 
499 template<typename T>
501  const std::string& name,
502  const DataPoints& cloud)
503 {
504  buildGenericAttributeStream(stream, "NORMALS", name, cloud, 3);
505 }
506 
507 template<typename T>
509  const std::string& name,
510  const DataPoints& cloud)
511 {
512  buildGenericAttributeStream(stream, "VECTORS", name, cloud, 3);
513 }
514 
515 template<typename T>
517  const std::string& name,
518  const DataPoints& cloud)
519 {
520  buildGenericAttributeStream(stream, "TENSORS", name, cloud, 9);
521 }
522 
523 template<typename T>
525  const std::string& name,
526  const DataPoints& cloud)
527 {
528  buildGenericAttributeStream(stream, "COLOR_SCALARS", name, cloud, 4);
529 }
530 
531 template<typename T>
533  const std::string& name,
534  const DataPoints& ref,
535  const DataPoints& reading)
536 {
537 
538  const Matrix descRef(ref.getDescriptorByName(name));
539  const Matrix descRead(reading.getDescriptorByName(name));
540 
541  if(descRef.rows() != 0 && descRead.rows() != 0)
542  {
543  stream << "SCALARS " << name << " float\n";
544  stream << "LOOKUP_TABLE default\n";
545 
546  stream << padWithZeros(
547  descRef, 1, ref.descriptors.cols()).transpose();
548  stream << "\n";
549  stream << padWithZeros(
550  descRead, 1, reading.descriptors.cols()).transpose();
551  stream << "\n";
552  }
553 }
554 
555 
556 template<typename T>
558  const std::string& name,
559  const DataPoints& ref,
560  const DataPoints& reading)
561 {
562 
563  const Matrix descRef(ref.getDescriptorByName(name));
564  const Matrix descRead(reading.getDescriptorByName(name));
565 
566  if(descRef.rows() != 0 && descRead.rows() != 0)
567  {
568  stream << "NORMALS " << name << " float\n";
569 
570  stream << padWithZeros(
571  descRef, 3, ref.descriptors.cols()).transpose();
572  stream << "\n";
573  stream << padWithZeros(
574  descRead, 3, reading.descriptors.cols()).transpose();
575  stream << "\n";
576  }
577 }
578 
579 
580 template<typename T>
582  const std::string& name,
583  const DataPoints& ref,
584  const DataPoints& reading)
585 {
586 
587  const Matrix descRef(ref.getDescriptorByName(name));
588  const Matrix descRead(reading.getDescriptorByName(name));
589 
590  if(descRef.rows() != 0 && descRead.rows() != 0)
591  {
592  stream << "VECTORS " << name << " " << getTypeName<T>() << "\n";
593 
594  stream << padWithZeros(
595  descRef, 3, ref.descriptors.cols()).transpose();
596  stream << "\n";
597  stream << padWithZeros(
598  descRead, 3, reading.descriptors.cols()).transpose();
599  stream << "\n";
600  }
601 }
602 
603 
604 template<typename T>
606  const std::string& name,
607  const DataPoints& ref,
608  const DataPoints& reading)
609 {
610 
611  const Matrix descRef(ref.getDescriptorByName(name));
612  const Matrix descRead(reading.getDescriptorByName(name));
613 
614  if(descRef.rows() != 0 && descRead.rows() != 0)
615  {
616  stream << "TENSORS " << name << " float\n";
617 
618  stream << padWithZeros(
619  descRef, 9, ref.descriptors.cols()).transpose();
620  stream << "\n";
621  stream << padWithZeros(
622  descRead, 9, reading.descriptors.cols()).transpose();
623  stream << "\n";
624  }
625 }
626 
627 template<typename T>
629 {
630  //TODO: this check is a reminder of the old implementation. Check
631  // if we still need that. FP
632  if (!cloud.timeExists(name))
633  return;
634 
635  const BOOST_AUTO(time, cloud.getTimeViewByName(name));
636  assert(time.rows() == 1);
637 
638  // Loop through the array to split the lower and higher part of int64_t
639  // TODO: if an Eigen matrix operator can do it without loop, change that
640 
641  Eigen::Matrix<uint32_t, 1, Eigen::Dynamic> high32(time.cols());
642  Eigen::Matrix<uint32_t, 1, Eigen::Dynamic> low32(time.cols());
643 
644  for(int i=0; i<time.cols(); i++)
645  {
646  high32(0, i) = (uint32_t)(time(0, i) >> 32);
647  low32(0, i) = (uint32_t)time(0, i);
648  }
649 
650  stream << "SCALARS" << " " << name << "_splitTime_high32" << " " << "unsigned_int" << "\n";
651  stream << "LOOKUP_TABLE default\n";
652 
653  writeVtkData(bWriteBinary, high32.transpose(), stream);
654 
655  stream << "\n";
656 
657  stream << "SCALARS" << " " << name << "_splitTime_low32" << " " << "unsigned_int" << "\n";
658  stream << "LOOKUP_TABLE default\n";
659 
660  writeVtkData(bWriteBinary, low32.transpose(), stream);
661 
662  stream << "\n";
663 }
664 
665 template<typename T>
667  const Matrix m,
668  const int expectedRow,
669  const int expectedCols)
670 {
671  assert(m.cols() <= expectedCols || m.rows() <= expectedRow);
672  if(m.cols() == expectedCols && m.rows() == expectedRow)
673  {
674  return m;
675  }
676  else
677  {
678  Matrix tmp = Matrix::Zero(expectedRow, expectedCols);
679  tmp.topLeftCorner(m.rows(), m.cols()) = m;
680  return tmp;
681  }
682 
683 }
684 
685 template<typename T>
687  const Matrix m,
688  const int expectedRow,
689  const int expectedCols)
690 {
691  assert(m.cols() <= expectedCols || m.rows() <= expectedRow);
692  if(m.cols() == expectedCols && m.rows() == expectedRow)
693  {
694  return m;
695  }
696  else
697  {
698  Matrix tmp = Matrix::Ones(expectedRow, expectedCols);
699  tmp.topLeftCorner(m.rows(), m.cols()) = m;
700  return tmp;
701  }
702 
703 }
704 
705 template<typename T>
706 void InspectorsImpl<T>::AbstractVTKInspector::finish(const size_t iterationCount)
707 {
708 }
709 
710 
711 //-----------------------------------
712 // VTK File inspector
713 
714 template<typename T>
716  AbstractVTKInspector("VTKFileInspector", VTKFileInspector::availableParameters(), params),
717  baseFileName(Parametrizable::get<string>("baseFileName")),
718  bDumpIterationInfo(Parametrizable::get<bool>("dumpIterationInfo")),
719  bDumpDataLinks(Parametrizable::get<bool>("dumpDataLinks")),
720  bDumpReading(Parametrizable::get<bool>("dumpReading")),
721  bDumpReference(Parametrizable::get<bool>("dumpReference"))
722 {
723 }
724 
725 template<typename T>
727 {
728 
729  if (!bDumpIterationInfo) return;
730 
731  ostringstream oss;
732  oss << baseFileName << "-iterationInfo.csv";
733  //std::cerr << "writing to " << oss.str() << std::endl;
734  LOG_INFO_STREAM("writing to " << oss.str());
735 
736  this->streamIter = new ofstream(oss.str().c_str());
737  if (this->streamIter->fail())
738  throw std::runtime_error("Couldn't open the file \"" + oss.str() + "\". Check if directory exist.");
739 
740 }
741 
742 template<typename T>
743 void InspectorsImpl<T>::VTKFileInspector::finish(const size_t iterationCount)
744 {
745  if (!bDumpIterationInfo) return;
746  closeStream(this->streamIter);
747 }
748 
749 template<typename T>
751 {
752  string filteredStr = role;
753  if(role.substr(role.size()-4,4) == ".vtk")
754  filteredStr = role.substr(0, role.size()-4);
755 
756  ostringstream oss;
757  if(baseFileName != "")
758  oss << baseFileName << "-" << filteredStr << ".vtk";
759  else
760  oss << filteredStr << ".vtk";
761 
762  //std::cerr << "writing to " << oss.str() << std::endl;
763  LOG_INFO_STREAM("writing to " << oss.str());
764  ofstream* file = new ofstream(oss.str().c_str(), std::ios::binary);
765  if (file->fail())
766  throw std::runtime_error("Couldn't open the file \"" + oss.str() + "\". Check if directory exist.");
767  return file;
768 }
769 
770 template<typename T>
771 std::ostream* InspectorsImpl<T>::VTKFileInspector::openStream(const std::string& role, const size_t iterationNumber)
772 {
773  ostringstream oss;
774  oss << baseFileName << "-" << role << "-" << iterationNumber << ".vtk";
775  ofstream* file = new ofstream(oss.str().c_str());
776  if (file->fail())
777  throw std::runtime_error("Couldn't open the file \"" + oss.str() + "\". Check if directory exist.");
778  return file;
779 }
780 
781 template<typename T>
783 {
784  delete stream;
785 }
786 
787 
788 
void dumpMeshNodes(const DataPoints &data, std::ostream &stream)
void buildNormalStream(std::ostream &stream, const std::string &name, const DataPoints &ref, const DataPoints &reading)
virtual void dumpIteration(const size_t iterationNumber, const TransformationParameters &parameters, const DataPoints &filteredReference, const DataPoints &reading, const Matches &matches, const OutlierWeights &outlierWeights, const TransformationCheckers &transformationCheckers)
Dump the state of a given iteration.
#define LOG_INFO_STREAM(args)
Matrix descriptors
descriptors of points in the cloud, might be empty
Definition: PointMatcher.h:333
bool timeExists(const std::string &name) const
Look if a time with a given name exist.
PointMatcherSupport::Histogram< double > Histogram
virtual void dumpStats(std::ostream &stream)
Dump all statistics in CSV format.
ConstView getDescriptorViewByName(const std::string &name) const
Get a const view on a descriptor by name, throw an exception if it does not exist.
void buildTensorStream(std::ostream &stream, const std::string &name, const DataPoints &ref, const DataPoints &reading)
std::string getTypeName()
::std::string string
Definition: gtest.h:1979
data
Definition: icp.py:50
void buildTimeStream(std::ostream &stream, const std::string &name, const DataPoints &cloud)
static const ParametersDoc availableParameters()
virtual void closeStream(std::ostream *stream)
const bool isBigEndian
true if platform is big endian
void dumpDataLinks(const DataPoints &ref, const DataPoints &reading, const Matches &matches, const OutlierWeights &featureOutlierWeights, std::ostream &stream)
Labels timeLabels
labels of times.
Definition: PointMatcher.h:336
VTKFileInspector(const Parameters &params=Parameters())
void buildGenericAttributeStream(std::ostream &stream, const std::string &attribute, const std::string &nameTag, const DataPoints &cloud, const int forcedDim)
std::ostream & writeVtkData(bool writeBinary, const Matrix &data, std::ostream &out)
Definition: IOFunctions.h:81
Eigen::Matrix< T, Eigen::Dynamic, Eigen::Dynamic > Matrix
A dense matrix over ScalarType.
Definition: PointMatcher.h:169
TimeConstView getTimeViewByName(const std::string &name) const
Get a const view on a time by name, throw an exception if it does not exist.
virtual void dumpStatsHeader(std::ostream &stream)
Dump header for all statistics.
virtual void closeStream(std::ostream *stream)=0
virtual std::ostream * openStream(const std::string &role)=0
virtual void finish(const size_t iterationCount)
Tell the inspector the ICP operation is completed.
std::map< std::string, Parameter > Parameters
Parameters stored as a map of string->string.
virtual void addStat(const std::string &name, double data)
Add a value for statistics name, create it if new.
Functions and classes that are not dependant on scalar type are defined in this namespace.
virtual void init()
Start a new ICP operation or sequence.
An inspector allows to log data at the different steps, for analysis.
Definition: PointMatcher.h:624
PointMatcher< T >::Matrix Matrix
ref
Definition: icp.py:49
void buildVectorStream(std::ostream &stream, const std::string &name, const DataPoints &ref, const DataPoints &reading)
PointMatcher< T >::OutlierWeights OutlierWeights
Result of the data-association step (Matcher::findClosests), before outlier rejection.
Definition: PointMatcher.h:371
bool descriptorExists(const std::string &name) const
Look if a descriptor with a given name exist.
Parameters parameters
parameters with their values encoded in string
void buildColorStream(std::ostream &stream, const std::string &name, const DataPoints &cloud)
const M::mapped_type & get(const M &m, const typename M::key_type &k)
A chain of TransformationChecker.
Definition: PointMatcher.h:611
AbstractVTKInspector(const std::string &className, const ParametersDoc paramsDoc, const Parameters &params)
#define LOG_WARNING_STREAM(args)
The superclass of classes that are constructed using generic parameters. This class provides the para...
const int oneBigEndian
is always a big endian independent of the platforms endianness
std::vector< ParameterDoc > ParametersDoc
The documentation of all parameters.
S get(const std::string &paramName)
Return the value of paramName, lexically-casted to S.
const std::string className
name of the class
PerformanceInspector(const std::string &className, const ParametersDoc paramsDoc, const Parameters &params)
Matrix padWithZeros(const Matrix m, const int expectedRow, const int expectedCols)
virtual void finish(const size_t iterationCount)
Tell the inspector the ICP operation is completed.
file
Definition: setup.py:28
virtual std::ostream * openStream(const std::string &role)
Matrix padWithOnes(const Matrix m, const int expectedRow, const int expectedCols)
void dumpDataPoints(const DataPoints &data, std::ostream &stream)
Ids ids
identifiers of closest points
Definition: PointMatcher.h:385
Matrix features
features of points in the cloud
Definition: PointMatcher.h:331
static constexpr int InvalidId
Definition: PointMatcher.h:377
void buildScalarStream(std::ostream &stream, const std::string &name, const DataPoints &ref, const DataPoints &reading)
Labels descriptorLabels
labels of descriptors
Definition: PointMatcher.h:334
PointMatcher< T >::TransformationParameters TransformationParameters


libpointmatcher
Author(s):
autogenerated on Sat May 27 2023 02:38:02