DGtal  1.5.beta
Rotationtables.h
1 
19 #pragma once
20 
30 #if defined(ROTATIONTABLES_RECURSES)
31 #error Recursive header files inclusion detected in Rotationtables.h
32 #else // defined(ROTATIONTABLES_RECURSES)
34 #define ROTATIONTABLES_RECURSES
35 
36 #if !defined ROTATIONTABLES_h
38 #define ROTATIONTABLES_h
39 
41 // Inclusions
42 #include "GAVector.h"
43 #include <iostream>
44 #include <vector>
45 #include <fcntl.h>
46 #include <sys/mman.h>
47 #include <sys/stat.h>
48 #include <unistd.h>
49 #include <utility>
50 namespace DGtal {
51  namespace functions {
57  template<typename TSpace, typename TInputValue = typename TSpace::Point>
58  std::vector<std::vector<int>> loadOTCTable(const std::string& tableFolderPath,const int rwidth) {
59  std::ostringstream ot;
60  ot << tableFolderPath <<"OT-" << rwidth << "-circles-l2.txt";
61  std::string tname = ot.str();
62  std::vector< int> Csize;
63  std::vector< std::vector< int > > table;
64  std::ifstream tinput( tname.c_str() );
65  if(tinput.fail()) {
66  std::cerr << "OTC file not found" <<std::endl;
67  }else{
68  bool size_mode = true;
69  int a = 0;
70  int nb_ok = 0;
71  while ( ! tinput.eof() )
72  {
73  int t;
74  double alpha;
75  std::string str;
76  std::getline( tinput, str );
77 
78  // ignore comments
79  if ( str.empty() || str[ 0 ] == '#' ) continue;
80  if ( size_mode ) {
81  std::istringstream is( str );
82  while ( is >> t ) Csize.push_back( t );
83  // std::cout << "Read #C=" << Csize.size() << std::endl;
84  size_mode = false;
85  } else {
86  std::istringstream is( str );
87  std::vector< int > mapping;
88  is >> alpha;
89  int ra = int( round( alpha*180.0/M_PI ) );
90  if ( a == ra ) nb_ok += 1;
91  mapping.push_back( 0 ); // add 0 circle
92  while ( is >> t ) mapping.push_back( t );
93  // std::cout << " #M=" << mapping.size() << std::endl;
94  table.push_back( mapping );
95  a += 1;
96  }
97  }
98  }
99  tinput.close();
100 
101  return table;
102  }
103 
104 
105  template<typename TSpace, typename TInputValue = typename TSpace::Point>
106  std::vector<std::string> parselineWithSeparator(const std::string& coordinatesStr,const char delimiter) {
107  std::vector<std::string> substrings;
108  std::istringstream iss(coordinatesStr);
109 
110  std::string substring;
111  while(std::getline(iss,substring,delimiter)) {
112  std::cout << "substring="<<substring<<std::endl;
113  substrings.push_back(substring);
114  }
115  return substrings;
116  }
117 
118 
120  template<typename TSpace, typename TInputValue = typename TSpace::Point>
121  std::vector<GAVector<TSpace>> parseCoordinates(const std::string& coordinatesStr) {
122  int x, y;
123  std::istringstream iss(coordinatesStr);
124  char delim;
125  std::vector<GAVector<TSpace>> gavecs;
126 
127  iss >> delim;
128  // Parse (x1,y1),(x2,y2),...,(xn,yn), n is even
129  while (iss >> x >> delim >> y) {
130  gavecs.push_back(GAVector<TSpace>({x, y}));
131  // std::cout << "x="<<x<<",y="<<y<<std::endl;
132  if (iss.peek() == ',' || iss.peek() == ')') {
133  iss >> delim >> delim>> delim;
134  } else {
135  break;
136  }
137  }
138  return gavecs;
139  }
140 
141  template<typename TSpace, typename TInputValue = typename TSpace::Point>
142  std::vector<std::tuple<std::vector<GAVector<TSpace>>,double,double>> loadFastCBDRTable(std::string fileStr) {
143  const char* filename =fileStr.c_str();
144  std::cout << "filename="<<filename<<std::endl;
145  // Open bijective file
146  int fileDesc = open(filename, O_RDONLY);
147  if (fileDesc == -1) {
148  std::cerr << "Fast table : Error opening file: " << strerror(errno) << std::endl;
149  std::cerr << "Fast table : Error file name= " << filename << std::endl;
150  return {};
151  }
152 
153  struct stat fileInfo;
154  if (fstat(fileDesc, &fileInfo) == -1) {
155  std::cerr << "file information error : " << strerror(errno) << std::endl;
156  close(fileDesc);
157  return {};
158  }
159  // Map the file into memory (file size can be ~200MB for kmax=30, n=4)
160  char* fileData = static_cast<char*>(mmap(NULL, fileInfo.st_size, PROT_READ, MAP_PRIVATE, fileDesc, 0));
161  if (fileData == MAP_FAILED) {
162  std::cerr << "Error mapping file to memory: " << strerror(errno) << std::endl;
163  close(fileDesc);
164  return {};
165  }
166 
167  // Read lines from the memory-mapped
168  size_t start = 0;
169 
170  std::vector<std::tuple<std::vector<GAVector<TSpace>>,double,double>> vecCompositionBijective_With_Errors;
171  std::cout << "file info size="<<fileInfo.st_size<<std::endl;
172  for (size_t i = 0; i < fileInfo.st_size; ++i) {
173  std::string linebefore(fileData + start, i - start + 1);
174  std::cout << "line before="<<linebefore<<std::endl;
175  if (fileData[i] == '\n' || i == fileInfo.st_size - 1) {
176  // Extract coordinates from the line
177  std::string line(fileData + start, i - start + 1);
178  std::cout << "line="<<line<<std::endl;
179  auto vectorsAndLinfLcont = parselineWithSeparator<TSpace,TInputValue>(line,';');
180  std::cout <<"1="<<vectorsAndLinfLcont[0]<<std::endl;
181  std::cout <<"2="<<vectorsAndLinfLcont[1]<<std::endl;
182  std::cout <<"3="<<vectorsAndLinfLcont[2]<<std::endl;
183 
184  std::vector<GAVector<TSpace>> coordinates;
185 
186  // Parse coordinates from the line
187  std::string coordinateStr;
188  coordinates = functions::parseCoordinates<TSpace>(vectorsAndLinfLcont[0]);
189  std::cout <<"fast : coord=";
190  for(auto gavec : coordinates)
191  std::cout <<gavec.my_gavec <<" ";
192  std::cout <<std::endl;
193  std::cout <<"fast two"<<vectorsAndLinfLcont[1]<<std::endl;
194  std::cout <<"fast three"<<vectorsAndLinfLcont[2]<<std::endl;
195  vecCompositionBijective_With_Errors.push_back(std::make_tuple(coordinates,std::stod(vectorsAndLinfLcont[1]),std::stod(vectorsAndLinfLcont[2])));
196  start = i + 1;
197  }
198  }
199 
200  munmap(fileData, fileInfo.st_size);
201  close(fileDesc);
202  std::cout << "load done .."<<std::endl;
203 
204  return vecCompositionBijective_With_Errors;
205  }
206 
207 
208  template<typename TSpace, typename TInputValue = typename TSpace::Point>
209  std::vector<std::pair<std::vector<GAVector<TSpace>>,GAVector<TSpace>>> loadBijectiveRotationTable(std::string fileStr, const size_t n, const size_t kmax) {
210  //std::string fileStr = (("../precomputedTables/"+(std::to_string(n))+"reflectionsUnique_kmax_"+std::to_string(kmax)+".txt")); //"../precomputedTables/2reflectionsUnique_kmax_15.txt";//
211  const char* filename =fileStr.c_str();
212 
213  // Open bijective file
214  int fileDesc = open(filename, O_RDONLY);
215  if (fileDesc == -1) {
216  std::cerr << "Error opening file: " << strerror(errno) << std::endl;
217  return {};
218  }
219 
220  // Get the size of the file
221  struct stat fileInfo;
222  if (fstat(fileDesc, &fileInfo) == -1) {
223  std::cerr << "file information error : " << strerror(errno) << std::endl;
224  close(fileDesc);
225  return {};
226  }
227 
228  // Map the file into memory (file size can be ~200MB for kmax=30, n=4)
229  char* fileData = static_cast<char*>(mmap(NULL, fileInfo.st_size, PROT_READ, MAP_PRIVATE, fileDesc, 0));
230  if (fileData == MAP_FAILED) {
231  std::cerr << "Error mapping file to memory: " << strerror(errno) << std::endl;
232  close(fileDesc);
233  return {};
234  }
235 
236  // Read lines from the memory-mapped
237  size_t start = 0;
238  bool isFirstLine = true;
239  int kmaxFile=0;
240 
241  std::vector<std::pair<std::vector<GAVector<TSpace>>,GAVector<TSpace>>> vecCompositionBijective;
242  for (size_t i = 0; i < fileInfo.st_size; ++i) {
243  if (fileData[i] == '\n' || i == fileInfo.st_size - 1) {
244  // Extract coordinates from the line
245  std::string line(fileData + start, i - start + 1);
246  if (isFirstLine) {
247  size_t pos = line.find("kmax=");
248  if (pos != std::string::npos) {
249  if (sscanf(line.c_str() + pos + 5, "%d", &kmaxFile) == 1) {
250  std::cout << "kmax: " << kmaxFile << std::endl;
251  }
252  }
253  isFirstLine = false;
254  } else {
255  std::vector<GAVector<TSpace>> coordinates;
256 
257  // Parse coordinates from the line
258  std::string coordinateStr;
259  coordinates = functions::parseCoordinates<TSpace>(line);
260  // Store the last coordinate separately
261  GAVector<TSpace> last = coordinates.back();
262  coordinates.pop_back(); // Exclude the last coordinate from the main vector
263  vecCompositionBijective.push_back(std::make_pair(coordinates,last));
264  }
265  start = i + 1;
266  }
267  }
268 
269  munmap(fileData, fileInfo.st_size);
270  close(fileDesc);
271  std::cout << "load done .."<<std::endl;
272  return vecCompositionBijective;
273  }
274 
275  }
276 }
277 
278 
279 #endif //ROTATIONTABLES
280 
281 #undef ROTATIONTABLES_RECURSES
282 #endif // else defined(ROTATIONTABLES_RECURSES)
std::vector< std::pair< std::vector< GAVector< TSpace > >, GAVector< TSpace > > > loadBijectiveRotationTable(std::string fileStr, const size_t n, const size_t kmax)
std::vector< std::tuple< std::vector< GAVector< TSpace > >, double, double > > loadFastCBDRTable(std::string fileStr)
std::vector< GAVector< TSpace > > parseCoordinates(const std::string &coordinatesStr)
parse line of CBDR tables
std::vector< std::vector< int > > loadOTCTable(const std::string &tableFolderPath, const int rwidth)
Rotation table loading : for OTC and RBDR.
std::vector< std::string > parselineWithSeparator(const std::string &coordinatesStr, const char delimiter)
DGtal is the top-level namespace which contains all DGtal functions and types.