vmmlib  1.7.0
 All Classes Namespaces Functions Pages
t3_converter.hpp
1 /*
2  * Copyright (c) 2006-2014, Visualization and Multimedia Lab,
3  * University of Zurich <http://vmml.ifi.uzh.ch>,
4  * Eyescale Software GmbH,
5  * Blue Brain Project, EPFL
6  *
7  * This file is part of VMMLib <https://github.com/VMML/vmmlib/>
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions are met:
11  *
12  * Redistributions of source code must retain the above copyright notice, this
13  * list of conditions and the following disclaimer. Redistributions in binary
14  * form must reproduce the above copyright notice, this list of conditions and
15  * the following disclaimer in the documentation and/or other materials provided
16  * with the distribution. Neither the name of the Visualization and Multimedia
17  * Lab, University of Zurich nor the names of its contributors may be used to
18  * endorse or promote products derived from this software without specific prior
19  * written permission.
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
24  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30  * POSSIBILITY OF SUCH DAMAGE.
31  */
32 
33 // class to read/write and convert tensor3 files (from raw, to csv...)
34 
35 #ifndef __VMML__T3_CONVERTER__HPP__
36 #define __VMML__T3_CONVERTER__HPP__
37 
38 #include <vmmlib/tensor3.hpp>
39 
40 namespace vmml {
41 
42  template< size_t I1, size_t I2, size_t I3, typename T = float >
44  {
45  public:
49 
50  template< typename T_convert >
51  static void convert_raw(const std::string& dir_, const std::string& in_filename_, const std::string& out_filename_);
52 
53  //header size as bytes
54  static void remove_uct_cylinder(const std::string& dir_,
55  const std::string& in_filename_,
56  const std::string& out_filename_,
57  const double& sigma_,
58  const size_t header_size_,
59  const size_t radius_offset_,
60  int seed_ = 0);
61 
62  static void export_to(const t3_t& input_, std::vector< T >& output_);
63  static void import_from(const std::vector< T >& input_, t3_t& output_);
64  static void write_to_raw(const t3_t& data_, const std::string& dir_, const std::string& filename_); // OK
65  static void read_from_raw(t3_t& data_, const std::string& dir_, const std::string& filename_); // OK
66  static void write_datfile(const std::string& dir_, const std::string& filename_);
67  static void write_to_csv(const t3_t& data_, const std::string& dir_, const std::string& filename_);
68  static void remove_normals_from_raw(const t3_t& data_, const std::string& dir_, const std::string& filename_);
69  static double rmse_from_files(const std::string& dir_, const std::string& filename_a_, const std::string& filename_b_ );
70 
71  template< typename TT >
72  static void quantize_to(const std::string& dir_,
73  const std::string& in_filename_, const std::string& out_filename_,
74  const T& min_value_, const T& max_value_);
75 
76 
77  protected:
78 
79  static void concat_path(const std::string& dir_, const std::string& filename_, std::string& path_);
80 
81  }; //end t3_converter
82 
83 
84 
85 #define VMML_TEMPLATE_STRING template< size_t I1, size_t I2, size_t I3, typename T >
86 #define VMML_TEMPLATE_CLASSNAME t3_converter< I1, I2, I3, T >
87 
88  VMML_TEMPLATE_STRING
89  template< typename TT >
90  void
91  VMML_TEMPLATE_CLASSNAME::quantize_to(const std::string& dir_,
92  const std::string& in_filename_, const std::string& out_filename_,
93  const T& min_value_, const T& max_value_) {
94  std::string path_in_raw = "";
95  std::string path_out_raw = "";
96  concat_path(dir_, in_filename_, path_in_raw);
97  concat_path(dir_, out_filename_, path_out_raw);
98 
99  std::ofstream outfile;
100  outfile.open(path_out_raw.c_str());
101 
102  std::ifstream infile;
103  infile.open(path_in_raw.c_str(), std::ios::in);
104 
105  if (infile.is_open() && outfile.is_open()) {
106  double max_tt_range = double((std::numeric_limits< TT >::max)());
107  double min_tt_range = double((std::numeric_limits< TT >::min)());
108  double tt_range = max_tt_range - min_tt_range;
109  double t_range = max_value_ - min_value_;
110 
111  //std::cout << "tt min= " << min_tt_range << ", tt max= " << max_tt_range << ", t min= " << min_value_ << ", t max= " << max_value_ << std::endl;
112  //std::cout << "tt range=" << tt_range << ", t range= " << t_range << std::endl;
113 
114  T* in_value;
115  TT out_value;
116  size_t len_in = sizeof (T);
117  size_t len_out = sizeof (TT);
118  char* data = new char[ len_in ];
119 
120  for (size_t i3 = 0; i3 < I3; ++i3) {
121  for (size_t i1 = 0; i1 < I1; ++i1) {
122  for (size_t i2 = 0; i2 < I2; ++i2) {
123  //read value
124  infile.read(data, len_in);
125  in_value = (T*)&(data[0]);
126 
127  //Quantize value
128  if (std::numeric_limits<TT>::is_signed) {
129  out_value = TT((std::min)((std::max)(min_tt_range, double((*in_value * tt_range / t_range) + 0.5)), max_tt_range));
130  } else {
131  out_value = TT((std::min)((std::max)(min_tt_range, double(((*in_value - min_value_) * tt_range / t_range) + 0.5)), max_tt_range));
132  }
133 
134  //write_value
135  outfile.write((char*) &(out_value), len_out);
136  }
137  }
138  }
139 
140  infile.close();
141  outfile.close();
142  } else {
143  infile.close();
144  outfile.close();
145  std::cout << "no file open" << std::endl;
146  }
147  }
148 
149  VMML_TEMPLATE_STRING
150  void
151  VMML_TEMPLATE_CLASSNAME::concat_path(const std::string& dir_, const std::string& filename_, std::string& path_) {
152  int dir_length = dir_.size() - 1;
153  int last_separator = dir_.find_last_of("/");
154  path_ = dir_;
155  if (last_separator < dir_length) {
156  path_.append("/");
157  }
158  path_.append(filename_);
159 
160  //check for format
161  if( filename_.find("raw", filename_.size() - 3) == std::string::npos )
162  {
163  path_.append(".");
164  path_.append("raw");
165  }
166  }
167 
168  VMML_TEMPLATE_STRING
169  template< typename T_convert >
170  void
171  VMML_TEMPLATE_CLASSNAME::convert_raw(const std::string& dir_, const std::string& in_filename_, const std::string& out_filename_) {
172  std::string path_in_raw = "";
173  std::string path_out_raw = "";
174  concat_path(dir_, in_filename_, path_in_raw);
175  concat_path(dir_, out_filename_, path_out_raw);
176 
177  std::ofstream outfile;
178  outfile.open(path_out_raw.c_str());
179 
180  std::ifstream infile;
181  infile.open(path_in_raw.c_str(), std::ios::in);
182 
183  if (infile.is_open() && outfile.is_open()) {
184  T* in_value;
185  T_convert out_value;
186  size_t len_in = sizeof (T);
187  size_t len_out = sizeof (T_convert);
188  char* data = new char[ len_in ];
189 
190  for (size_t i3 = 0; i3 < I3; ++i3) {
191  for (size_t i1 = 0; i1 < I1; ++i1) {
192  for (size_t i2 = 0; i2 < I2; ++i2) {
193  infile.read(data, len_in);
194  in_value = (T*)&(data[0]);
195  out_value = static_cast<T_convert> (*in_value);
196  outfile.write((char*) &(out_value), len_out);
197  }
198  }
199  }
200 
201  infile.close();
202  outfile.close();
203  } else {
204  infile.close();
205  outfile.close();
206  std::cout << "no file open" << std::endl;
207  }
208  }
209 
210  VMML_TEMPLATE_STRING
211  void
212  VMML_TEMPLATE_CLASSNAME::remove_uct_cylinder(const std::string& dir_,
213  const std::string& in_filename_,
214  const std::string& out_filename_,
215  const double& sigma_,
216  const size_t header_size_,
217  const size_t radius_offset_,
218  int seed_) {
219  std::string path_in_raw = "";
220  std::string path_out_raw = "";
221  concat_path(dir_, in_filename_, path_in_raw);
222  concat_path(dir_, out_filename_, path_out_raw);
223 
224  std::ofstream outfile;
225  outfile.open(path_out_raw.c_str());
226 
227  std::ifstream infile;
228  infile.open(path_in_raw.c_str(), std::ios::in);
229 
230  //for noise adding in outer area
231  if (seed_ >= 0)
232  srand(seed_);
233 
234  double length = 0;
235  double radius = (I1 - 1.0) / 2.0 - radius_offset_;
236  radius *= radius;
237  double k1 = 0;
238  double k2 = 0;
239  double fill_value = 0;
240 
241  if (infile.is_open() && outfile.is_open()) {
242  T* in_value;
243  T out_value;
244  size_t len_val = sizeof (T);
245  char* data = new char[ len_val ];
246 
247  //skip header
248  infile.read(data, header_size_);
249 
250  //Read/write data
251  for (size_t i3 = 0; i3 < I3; ++i3) {
252  for (size_t i1 = 0; i1 < I1; ++i1) {
253  k1 = i1 - (I1 - 1.0) / 2.0;
254  for (size_t i2 = 0; i2 < I2; ++i2) {
255  infile.read(data, len_val);
256  in_value = (T*)&(data[0]);
257  fill_value = static_cast<T> (*in_value);
258 
259  //check if value is outside cylinder
260  k2 = i2 - (I2 - 1.0) / 2.0;
261  length = k1 * k1 + k2*k2;
262  if (length >= radius) {
263  fill_value = rand();
264  fill_value /= RAND_MAX;
265  fill_value *= sigma_;
266  }
267 
268  out_value = static_cast<T> (fill_value);
269  outfile.write((char*) &(out_value), len_val);
270  }
271  }
272  }
273 
274  infile.close();
275  outfile.close();
276  } else {
277  infile.close();
278  outfile.close();
279  std::cout << "no file open" << std::endl;
280  }
281  }
282 
283  VMML_TEMPLATE_STRING
284  void
285  VMML_TEMPLATE_CLASSNAME::export_to(const t3_t& input_, std::vector< T >& output_) {
286  output_.clear();
287  const_iterator it = input_.begin(),
288  it_end = input_.end();
289  for (; it != it_end; ++it) {
290  output_.push_back(*it);
291  }
292  }
293 
294  VMML_TEMPLATE_STRING
295  void
296  VMML_TEMPLATE_CLASSNAME::import_from(const std::vector< T >& input_, t3_t& output_) {
297  size_t i = 0; //iterator over data_
298  size_t input_size = input_.size();
299 
300  iterator it = output_.begin(),
301  it_end = output_.end();
302  for (; it != it_end; ++it, ++i) {
303  if (i >= input_size)
304  *it = static_cast<T> (0);
305  else
306  *it = input_.at(i);
307  }
308  }
309 
310  VMML_TEMPLATE_STRING
311  void
312  VMML_TEMPLATE_CLASSNAME::remove_normals_from_raw(const t3_t& data_, const std::string& dir_, const std::string& filename_) {
313  int dir_length = dir_.size() - 1;
314  int last_separator = dir_.find_last_of("/");
315  std::string path = dir_;
316  if (last_separator < dir_length) {
317  path.append("/");
318  }
319  path.append(filename_);
320 
321 
322  size_t max_file_len = 2147483648u - sizeof (T);
323  size_t len_data = sizeof (T) * data_.SIZE;
324  size_t len_value = sizeof (T) * 4; //three normals per scalar value
325  size_t len_read = 0;
326  char* data = new char[ len_data ];
327  std::ifstream infile;
328  infile.open(path.c_str(), std::ios::in);
329 
330  if (infile.is_open()) {
331  tensor3_iterator<T> it = data_.begin(),
332  it_end = data_.end();
333 
334  size_t counter = 0;
335  while (len_data > 0) {
336  len_read = (len_data % max_file_len) > 0 ? len_data % max_file_len : len_data;
337  len_data -= len_read;
338  infile.read(data, len_read);
339 
340  T* T_ptr = (T*)&(data[0]);
341  for (; (it != it_end) && (len_read > 0); ++it, len_read -= len_value) {
342  ++T_ptr;
343  ++T_ptr;
344  ++T_ptr;
345  *it = *T_ptr;
346  ++T_ptr;
347  ++counter;
348  }
349  }
350 
351  delete[] data;
352  infile.close();
353  } else {
354  std::cout << "no file open" << std::endl;
355  }
356 
357  std::cout << "converted normals" << std::endl;
358 
359  std::string filename = "";
360  filename = filename_.substr(0, filename_.size() - 6);
361 
362 
363  write_datfile(".", filename);
364  write_to_raw(".", filename);
365  }
366 
367  VMML_TEMPLATE_STRING
368  void
369  VMML_TEMPLATE_CLASSNAME::read_from_raw(t3_t& data_, const std::string& dir_, const std::string& filename_) {
370  int dir_length = dir_.size() - 1;
371  int last_separator = dir_.find_last_of("/");
372  std::string path = dir_;
373  if (last_separator < dir_length) {
374  path.append("/");
375  }
376  path.append(filename_);
377 
378  size_t max_file_len = 2147483648u - sizeof (T);
379  size_t len_data = sizeof (T) * data_.SIZE;
380  size_t len_read = 0;
381  char* data = new char[ len_data ];
382  std::ifstream infile;
383  infile.open(path.c_str(), std::ios::in);
384 
385  if (infile.is_open()) {
386  tensor3_iterator<t3_t> it = data_.begin(),
387  it_end = data_.end();
388 
389  while (len_data > 0) {
390  len_read = (len_data % max_file_len) > 0 ? len_data % max_file_len : len_data;
391  len_data -= len_read;
392  infile.read(data, len_read);
393 
394  T* T_ptr = (T*)&(data[0]);
395  for (; (it != it_end) && (len_read > 0); ++it, len_read -= sizeof (T)) {
396  *it = *T_ptr;
397  ++T_ptr;
398  }
399  }
400 
401  delete[] data;
402  infile.close();
403  } else {
404  std::cout << "no file open" << std::endl;
405  }
406 
407  }
408 
409  VMML_TEMPLATE_STRING
410  void
411  VMML_TEMPLATE_CLASSNAME::write_to_raw(const t3_t& data_, const std::string& dir_, const std::string& filename_) {
412  int dir_length = dir_.size() - 1;
413  int last_separator = dir_.find_last_of("/");
414  std::string path = dir_;
415  if (last_separator < dir_length) {
416  path.append("/");
417  }
418  path.append(filename_);
419  //check for format
420  if (filename_.find("raw", filename_.size() - 3) == std::string::npos) {
421  path.append(".");
422  path.append("raw");
423  }
424  std::string path_raw = path;
425 
426  std::ofstream outfile;
427  outfile.open(path_raw.c_str());
428  if (outfile.is_open()) {
429  size_t len_slice = sizeof (T) * I1 * I2;
430  for (size_t index = 0; index < I3; ++index) {
431  outfile.write((char*) &(data_.get_frontal_slice_fwd(index)), len_slice);
432  }
433  outfile.close();
434  } else {
435  outfile.close();
436  std::cout << "no file open" << std::endl;
437  }
438  }
439 
440  VMML_TEMPLATE_STRING
441  void
442  VMML_TEMPLATE_CLASSNAME::write_datfile(const std::string& dir_, const std::string& filename_) {
443  int dir_length = dir_.size() - 1;
444  int last_separator = dir_.find_last_of("/");
445  std::string path = dir_;
446  if (last_separator < dir_length) {
447  path.append("/");
448  }
449 
450  std::string filename = filename_;
451  const size_t pos = filename_.size();
452  if ((filename_.find(".raw", pos) + 4 == pos) ||
453  (filename_.find(".dat", pos) + 4 == pos))
454  {
455  filename = filename_.substr(0, filename_.size() - 4);
456  }
457  path.append(filename);
458  //check for format
459  if (filename_.find("dat", filename_.size() - 3) == std::string::npos) {
460  path.append(".");
461  path.append("dat");
462  }
463 
464  std::string path_dat = path;
465 
466  const char* format = (sizeof (T) == 2) ? "USHORT" : "UCHAR";
467 
468  FILE* datfile = fopen(path_dat.c_str(), "w");
469  fprintf(datfile, "ObjectFileName:\t%s.raw\n", filename.c_str());
470  fprintf(datfile, "TaggedFileName:\t---\nResolution:\t%i %i %i\n", int(I1), int(I2), int(I3));
471  fprintf(datfile, "SliceThickness:\t1.0 1.0 1.0\n");
472  fprintf(datfile, "Format:\t%s\nNbrTags:\t0\n", format);
473  fprintf(datfile, "ObjectType:\tTEXTURE_VOLUME_OBJECT\nObjectModel:\tI\nGridType:\tEQUIDISTANT\n");
474  fprintf(datfile, "Modality:\tunknown\nTimeStep:\t0\n");
475  fclose(datfile);
476  }
477 
478  VMML_TEMPLATE_STRING
479  void
480  VMML_TEMPLATE_CLASSNAME::write_to_csv(const t3_t& data_, const std::string& dir_, const std::string& filename_) {
481  int dir_length = dir_.size() - 1;
482  int last_separator = dir_.find_last_of("/");
483  std::string path = dir_;
484  if (last_separator < dir_length) {
485  path.append("/");
486  }
487  path.append(filename_);
488  //check for format
489  if (filename_.find("csv", filename_.size() - 3) == std::string::npos)
490  {
491  path.append(".");
492  path.append("csv");
493  }
494 
495  std::ofstream outfile;
496  outfile.open(path.c_str());
497  if (outfile.is_open()) {
498 
499  for (size_t i = 0; i < I3; ++i) {
500  outfile << data_.get_frontal_slice_fwd(i) << std::endl;
501  }
502 
503  outfile.close();
504  } else {
505  std::cout << "no file open" << std::endl;
506  }
507 
508  }
509 
510  VMML_TEMPLATE_STRING
511  double
512  VMML_TEMPLATE_CLASSNAME::rmse_from_files(const std::string& dir_,
513 const std::string& filename_a_, const std::string& filename_b_ ) {
514  std::string path_a_raw = "";
515  std::string path_b_raw = "";
516  concat_path( dir_, filename_a_, path_a_raw );
517  concat_path( dir_, filename_b_, path_b_raw );
518 
519  std::ifstream afile;
520  afile.open( path_a_raw.c_str(), std::ios::in);
521 
522  std::ifstream bfile;
523  bfile.open( path_b_raw.c_str(), std::ios::in);
524 
525  double mse_val = 0.0f;
526  double mse_val_avg = 0.0f;
527  double mse_val_i3 = 0.0f;
528  double diff = 0.0f;
529 
530  if (afile.is_open() && bfile.is_open()) {
531  T* a_value;
532  T* b_value;
533  double a_value_f;
534  double b_value_f;
535 
536  size_t value_len = sizeof (T);
537  char* data_a = new char[ value_len ];
538  char* data_b = new char[ value_len ];
539 
540  for (size_t i3 = 0; i3 < I3; ++i3) {
541  mse_val = 0.0f;
542  for (size_t i1 = 0; i1 < I1; ++i1) {
543  for (size_t i2 = 0; i2 < I2; ++i2) {
544  afile.read( data_a, value_len);
545  a_value = (T*)&(data_a[0]);
546  a_value_f = static_cast<double> (*a_value);
547 
548  bfile.read( data_b, value_len);
549  b_value = (T*)&(data_b[0]);
550  b_value_f = static_cast<double> (*b_value);
551 
552  diff = fabs(b_value_f - a_value_f);
553  diff *= diff;
554  mse_val += diff;
555  }
556  }
557  mse_val_avg = mse_val;
558  mse_val_avg /= double(I1);
559  mse_val_avg /= double(I2);
560  mse_val_i3 += mse_val_avg;
561 
562  }
563 
564 
565  afile.close();
566  bfile.close();
567  } else {
568  afile.close();
569  bfile.close();
570  std::cout << "no file open" << std::endl;
571  }
572 
573 
574  mse_val_i3 /= double(I3);
575  return sqrt(mse_val_i3);
576  }
577 
578 
579 #undef VMML_TEMPLATE_STRING
580 #undef VMML_TEMPLATE_CLASSNAME
581 
582 
583 }//end vmml namespace
584 
585 #endif