SLIP  1.4
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
io_tools.hpp
Go to the documentation of this file.
1 /*
2  * Copyright(c):
3  * Signal Image and Communications (SIC) Department
4  * http://www.sic.sp2mi.univ-poitiers.fr/
5  * - University of Poitiers, France http://www.univ-poitiers.fr
6  * - XLIM Institute UMR CNRS 7252 http://www.xlim.fr/
7  *
8  * and
9  *
10  * D2 Fluid, Thermic and Combustion
11  * - University of Poitiers, France http://www.univ-poitiers.fr
12  * - PPRIME Institute - UPR CNRS 3346 http://www.pprime.fr
13  * - ISAE-ENSMA http://www.ensma.fr
14  *
15  * Contributor(s):
16  * The SLIP team,
17  * Benoit Tremblais <tremblais_AT_sic.univ-poitiers.fr>,
18  * Laurent David <laurent.david_AT_lea.univ-poitiers.fr>,
19  * Ludovic Chatellier <ludovic.chatellier_AT_univ-poitiers.fr>,
20  * Lionel Thomas <lionel.thomas_AT_univ-poitiers.fr>,
21  * Denis Arrivault <arrivault_AT_sic.univ-poitiers.fr>,
22  * Julien Dombre <julien.dombre_AT_univ-poitiers.fr>.
23  *
24  * Description:
25  * The Simple Library of Image Processing (SLIP) is a new image processing
26  * library. It is written in the C++ language following as much as possible
27  * the ISO/ANSI C++ standard. It is consequently compatible with any system
28  * satisfying the ANSI C++ complience. It works on different Unix , Linux ,
29  * Mircrosoft Windows and Mac OS X plateforms. SLIP is a research library that
30  * was created by the Signal, Image and Communications (SIC) departement of
31  * the XLIM, UMR 7252 CNRS Institute in collaboration with the Fluids, Thermic
32  * and Combustion departement of the P', UPR 3346 CNRS Institute of the
33  * University of Poitiers.
34  *
35  * The SLIP Library source code has been registered to the APP (French Agency
36  * for the Protection of Programs) by the University of Poitiers and CNRS,
37  * under registration number IDDN.FR.001.300034.000.S.P.2010.000.21000.
38 
39  * http://www.sic.sp2mi.univ-poitiers.fr/slip/
40  *
41  * This software is governed by the CeCILL-C license under French law and
42  * abiding by the rules of distribution of free software. You can use,
43  * modify and/ or redistribute the software under the terms of the CeCILL-C
44  * license as circulated by CEA, CNRS and INRIA at the following URL
45  * http://www.cecill.info.
46  * As a counterpart to the access to the source code and rights to copy,
47  * modify and redistribute granted by the license, users are provided only
48  * with a limited warranty and the software's author, the holder of the
49  * economic rights, and the successive licensors have only limited
50  * liability.
51  *
52  * In this respect, the user's attention is drawn to the risks associated
53  * with loading, using, modifying and/or developing or reproducing the
54  * software by the user in light of its specific status of free software,
55  * that may mean that it is complicated to manipulate, and that also
56  * therefore means that it is reserved for developers and experienced
57  * professionals having in-depth computer knowledge. Users are therefore
58  * encouraged to load and test the software's suitability as regards their
59  * requirements in conditions enabling the security of their systems and/or
60  * data to be ensured and, more generally, to use and operate it in the
61  * same conditions as regards security.
62  *
63  * The fact that you are presently reading this means that you have had
64  * knowledge of the CeCILL-C license and that you accept its terms.
65  */
66 
67 
68 
75 #ifndef SLIP_IO_TOOLS_HPP
76 #define SLIP_IO_TOOLS_HPP
77 
78 #include <ios>
79 #include <stdexcept>
80 #include <iostream>
81 #include <iterator>
82 #include <iomanip>
83 #include <sstream>
84 #include <string>
85 #include <fstream>
86 #include <algorithm>
87 #include "error.hpp"
88 //read/write image with ImageMagick
89 //
90 // -> Adding the macro condition HAVE_MAGICK for
91 // breaking the ImageMagick dependency
92 // Author : denis.arrivault\AT\inria.fr
93 // Date : 2013/02/06
94 // \since 1.4.0
95 #ifdef HAVE_MAGICK
96 #include <wand/magick_wand.h>
97 #include <magick/api.h>
98 #endif
99 
100 #include <cstdio>
101 #include <cstdlib>
102 #include "Array.hpp"
103 #include "Matrix.hpp"
104 #include "Point2d.hpp"
105 #include "Point3d.hpp"
106 #include "stride_iterator.hpp"
107 #include <boost/tokenizer.hpp>
108 
109 
110 #ifdef HAVE_MAGICK
111 //Macro for ImageMagick Input/Output exceptions
112 #define ThrowWandException(wand) \
113 { \
114  char \
115  *description; \
116  \
117  ExceptionType \
118  severity; \
119  \
120  description=MagickGetException(wand,&severity); \
121  (void) fprintf(stderr,"%s %s %lu %s\n",GetMagickModule(),description); \
122  description=(char *) MagickRelinquishMemory(description); \
123  exit(-1); \
124 }
125 #endif//HAVE_MAGICK
126 
127 namespace slip
128 {
129 
131  /* @{ */
132 
158  inline
159  std::size_t split_extension(const std::string& file_path_name,
160  std::string& file_path_name_cut,
161  std::string& ext)
162  {
163  std::size_t pos_point = file_path_name.find_last_of(".");
164  ext = file_path_name.substr(pos_point,file_path_name.length() - 1);
165  file_path_name_cut = file_path_name.substr(0,pos_point);
166  return pos_point;
167  }
168 
202  inline
203  std::string compose_file_name(const std::string& file_path_name,
204  const std::size_t img)
205  {
206 
207  std::size_t pos_purcent = file_path_name.find_last_of("%");
208  std::size_t pos_after_purcent = pos_purcent + 3;
209  std::size_t format_lenght = (std::size_t)atoi(&file_path_name[pos_purcent+1]);
210  std::string base_name = file_path_name.substr(0,pos_purcent);
211  std::string extension = file_path_name.substr(pos_after_purcent,file_path_name.length()-1);
212 
213  std::ostringstream ost;
214  ost.width(format_lenght);
215  ost.fill('0');
216  ost<<img;
217  return (base_name+ost.str())+extension;
218  }
219 
220 
221 
222 
223 
245  template <typename Container>
246  void print(const Container& C, const std::string& name = "")
247  {
248  if(name != "")
249  {
250  std::cout<<name<<" = "<<std::endl;
251  }
252  std::cout<<C<<std::endl;
253  }
254 
255 
256 
257 
258 
259  /* @} */
260 
262  /* @{ */
288  template <typename InputIterator>
289  inline
290  void write_raw(InputIterator first,
291  InputIterator last,
292  const std::string& file_path_name)
293  {
294  std::ofstream output(file_path_name.c_str(),std::ios::out);
295  try
296  {
297  if(!output)
298  {
299  throw std::ios_base::failure(slip::FILE_OPEN_ERROR + file_path_name);
300  }
301 
302  typedef typename std::iterator_traits<InputIterator>::value_type value_type;
303 
304  int size = last - first;
305  output.write((const char*)first,size * sizeof(value_type));
306  output.close();
307  }
308  catch(std::exception& e)
309  {
310  std::cerr<<e.what()<<std::endl;
311  output.close();
312  exit(1);
313  }
314 
315  }
316 
343  template <typename InputIterator>
344  inline
345  void read_raw(const std::string& file_path_name,
346  InputIterator first,
347  InputIterator last)
348  {
349  std::ifstream input(file_path_name.c_str(),std::ios::in);
350  try
351  {
352  if (!input)
353  {
354  throw std::ios_base::failure(slip::FILE_OPEN_ERROR + file_path_name);
355  }
356  typedef typename std::iterator_traits<InputIterator>::value_type value_type;
357  input.read((char*)first,(last-first)*sizeof(value_type));
358  }
359  catch(std::exception& e)
360  {
361  std::cerr<<e.what()<<std::endl;
362  input.close();
363  exit(1);
364  }
365 
366  }
367 
368  /* @} */
369 
371  /* @{ */
372 
406  template <typename RandomAccessIterator2d, typename WriteType>
407  inline
408  void write_ascii_2d(RandomAccessIterator2d upper_left,
409  RandomAccessIterator2d bottom_right,
410  const std::string& file_path_name)
411  {
412 
413  std::ofstream output(file_path_name.c_str(),std::ios::out);
414  try
415  {
416  if(!output)
417  {
418  throw std::ios_base::failure(slip::FILE_OPEN_ERROR + file_path_name);
419  }
420 
421 
422  typename RandomAccessIterator2d::difference_type size2d
423  = bottom_right - upper_left;
424 
425  std::size_t nb_lig = size2d[0];
426  std::size_t nb_col = size2d[1];
427 
428  RandomAccessIterator2d it2d = upper_left;
429  for(std::size_t i = 0; i < nb_lig; i++)
430  {
431  for(std::size_t j = 0; j < nb_col; j++)
432  {
433  output<<*it2d<<" ";
434  ++it2d;
435  }
436  output<<std::endl;
437  }
438  output.close();
439  }
440  catch(std::exception& e)
441  {
442  std::cerr<<e.what()<<std::endl;
443  output.close();
444  exit(1);
445  }
446 
447  }
448 
473  template <typename Container2d, typename WriteType>
474  inline
475  void write_ascii_2d(const Container2d& cont,
476  const std::string& file_path_name)
477  {
478  std::ofstream output(file_path_name.c_str(),std::ios::out);
479  try
480  {
481  if(!output)
482  {
483  throw std::ios_base::failure(slip::FILE_OPEN_ERROR + file_path_name);
484  }
485 
486 
487  typedef typename Container2d::size_type size_type;
488  size_type nb_lig = cont.rows();
489  size_type nb_col = cont.cols();
490 
491  for(size_type i = 0; i < nb_lig; i++)
492  {
493  for(size_type j = 0; j < nb_col; j++)
494  {
495  output<<(WriteType)cont[i][j]<<" ";
496  }
497  output<<std::endl;
498  }
499  output.close();
500  }
501  catch(std::exception& e)
502  {
503  std::cerr<<e.what()<<std::endl;
504  output.close();
505  exit(1);
506  }
507  }
508 
542  template <typename Container2d>
543  inline
544  void read_ascii_2d(Container2d& container,
545  const std::string& file_path_name)
546  {
547  std::ifstream input;
548 
549  try
550  {
551  input.open(file_path_name.c_str());
552  if(!input)
553  {
554  throw std::ios_base::failure(slip::FILE_OPEN_ERROR + file_path_name);
555  }
556 
557  //computes the number of rows
558  int nr = 0;
559  int nhead = 0; //number of head (comment) lines
560  std::string line;
561  while ( std::getline(input, line ) && line.length()!=0)
562  {
563  ++nr;
564  //check for comment lines (starting with either # % ! //
565  //or ")
566  std::size_t first_non_space = line.find_first_not_of(' ');
567 
568  if(line[first_non_space] =='#' || line[first_non_space]=='%' || line[first_non_space]=='!' || line[first_non_space]=='/' || line[first_non_space]=='"' || isalpha(line[first_non_space]))
569  {
570  nhead++;
571  }
572 
573 
574  }
575  nr = nr - nhead;
576 
577  //nr-=1;
578  // nr = line_number_ascii_file(input);
579  //computes the number of columns
580  int nc = 0;
581  input.seekg(0,std::ios::beg);
582  input.close();
583  std::ifstream input;
584  input.open(file_path_name.c_str());
585  if(!input)
586  {
587  throw std::ios_base::failure(slip::FILE_OPEN_ERROR + file_path_name);
588  }
589  //skip head lines
590  for(int n = 0; n < nhead; ++n)
591  {
592  std::getline(input, line);
593  }
594  std::getline(input, line );
595  boost::char_separator<char> sep(" \t");
596  boost::tokenizer<boost::char_separator<char> > tok(line,sep);
597  for(boost::tokenizer<boost::char_separator<char> >::iterator beg=tok.begin(); beg!=tok.end();++beg)
598  {
599  ++nc;
600  }
601 
602  container.resize((std::size_t)nr,(std::size_t)nc);
603  //reading datas
604  input.seekg(0,std::ios::beg);
605  //skip head lines
606  for(int n = 0; n < nhead; ++n)
607  {
608  std::getline(input, line);
609  }
610 
611 
612  for(int i = 0; i < nr; ++i)
613  {
614  for(int j = 0;j < nc; ++j)
615  {
616  typename Container2d::value_type tmp;
617  input>>tmp;
618  container[i][j] = tmp;
619  }
620  }
621  input.close();
622 
623  }
624  catch(std::exception& e)
625  {
626  std::cerr<<e.what()<<std::endl;
627  input.close();
628  exit(1);
629  }
630 
631  }
632 
633 
656  // template <typename RandomAccessIterator2d, typename WriteType>
657  // inline
658  // void write_tecplot_2d(RandomAccessIterator2d upper_left,
659  // RandomAccessIterator2d bottom_right,
660  // const std::string& file_path_name,
661  // const std::string& title,
662  // const std::string& zone)
663  // {
664  // std::ofstream output(file_path_name.c_str(),std::ios::out);
665  // try
666  // {
667  // if(!output)
668  // {
669  // throw std::ios_base::failure(slip::FILE_OPEN_ERROR + file_path_name); }
670 
671  // typename RandomAccessIterator2d::difference_type size2d
672  // = bottom_right - upper_left;
673  // std::size_t nb_lig = size2d[0];
674  // std::size_t nb_col = size2d[1];
675  // output<<"TITLE=\""<<title<<"\""<<std::endl;
676  // output<<"VARIABLES=\"x\" \"y\" \"I\"" << std::endl;
677  // output<<"ZONE T=\""<<zone<<"\", I="<<nb_col<<", J="<<nb_lig<<" F=POINT"<<std::endl;
678 
679  // RandomAccessIterator2d it2d = upper_left;
680  // for(std::size_t i = 0; i < nb_lig; i++)
681  // {
682  // for(std::size_t j = 0; j < nb_col; j++)
683  // {
684  // //output<<*it2d<<" ";
685  // output << j << " " << i << " " << *it2d << std::endl;
686  // ++it2d;
687  // }
688  // output<<std::endl;
689  // }
690  // output<<std::endl;
691  // output.close();
692  // }
693  // catch(std::exception& e)
694  // {
695  // std::cerr<<e.what()<<std::endl;
696  // output.close();
697  // exit(1);
698  // }
699  // }
700  template <typename RandomAccessIterator2d, typename WriteType>
701  inline
702  void write_tecplot_2d(RandomAccessIterator2d upper_left,
703  RandomAccessIterator2d bottom_right,
704  const std::string& file_path_name,
705  const std::string& title,
706  const std::string& zone,
707  const int precision = 6)
708  {
709  std::ofstream output(file_path_name.c_str(),std::ios::out);
710  try
711  {
712  if(!output)
713  {
714  throw std::ios_base::failure(slip::FILE_OPEN_ERROR + file_path_name); }
715  int default_precision = output.precision();
716  output.setf(std::ios::scientific);
717  output.precision(precision);
718  typename RandomAccessIterator2d::difference_type size2d
719  = bottom_right - upper_left;
720  const std::size_t nb_lig = size2d[0];
721  const std::size_t nb_col = size2d[1];
722  output<<"TITLE=\""<<title<<"\""<<std::endl;
723  output<<"VARIABLES=\"x\" \"y\" \"I\"" << std::endl;
724  output<<"ZONE T=\""<<zone<<"\", I="<<nb_col<<", J="<<nb_lig<<" F=POINT"<<std::endl;
725 
726  RandomAccessIterator2d it2d = upper_left;
727  for(std::size_t i = 0; i < nb_lig; i++)
728  {
729  for(std::size_t j = 0; j < nb_col; j++)
730  {
731  //output<<*it2d<<" ";
732  output << j << " " << i << " " << *it2d << std::endl;
733  ++it2d;
734  }
735  output<<std::endl;
736  }
737  output<<std::endl;
738  output.precision(default_precision);
739  output.close();
740  }
741  catch(std::exception& e)
742  {
743  std::cerr<<e.what()<<std::endl;
744  output.close();
745  exit(1);
746  }
747  }
748  /* @} */
749 
751  /* @{ */
752 
775  template <typename MultiContainer2d>
776  inline
777  void write_gnuplot_vect2d(const MultiContainer2d& field,
778  const std::string& file_path_name,
779  const int precision = 6)
780  {
781  std::ofstream output(file_path_name.c_str(),std::ios::out);
782  try
783  {
784  if(!output)
785  {
786  throw std::ios_base::failure(slip::FILE_OPEN_ERROR + file_path_name);
787  }
788  typedef typename MultiContainer2d::block_value_type T;
789  int default_precision = output.precision();
790  output.setf(std::ios::scientific);
791  output.precision(precision);
792  int dim1 = static_cast<int>(field.dim1());
793  int dim2 = static_cast<int>(field.dim2());
794  T y = T(0);
795  for(int i = dim1 - 1; i >= 0 ; --i, y+=T(1))
796  {
797  T x = T(0);
798  for(int j = 0; j < dim2; ++j,x+=T(1))
799  {
800  output<<static_cast<T>(x)<<" "<<static_cast<T>(y)<<" "<<field[i][j][0]<<" "<<field[i][j][1]<<"\n";
801  }
802  }
803  output.precision(default_precision);
804  output.close();
805  }
806  catch(std::exception& e)
807  {
808  std::cerr<<e.what()<<std::endl;
809  output.close();
810  exit(1);
811  }
812 
813  }
814 
815 
842  template <typename MultiContainer2d,typename T>
843  inline
844  void write_gnuplot_vect2d(const MultiContainer2d& field,
845  const slip::Point2d<T>& init_point,
846  const slip::Point2d<T>& step,
847  const std::string& file_path_name,
848  const int precision = 6)
849  {
850  std::ofstream output(file_path_name.c_str(),std::ios::out);
851  try
852  {
853  if(!output)
854  {
855  throw std::ios_base::failure(slip::FILE_OPEN_ERROR + file_path_name);
856  }
857  int default_precision = output.precision();
858  output.setf(std::ios::scientific);
859  output.precision(precision);
860  int dim1 = static_cast<int>(field.dim1());
861  int dim2 = static_cast<int>(field.dim2());
862 
863  T y=init_point[1];
864  for(int i=dim1-1; i >= 0;--i,y+=step[1])
865  {
866  T x=init_point[0];
867  for(int j=0; j < dim2; ++j,x+=step[0])
868  {
869  output<<static_cast<T>(x)<<" "<<static_cast<T>(y)<<" "<<field[i][j][0]<<" "<<field[i][j][1]<<"\n";
870  }
871  }
872  output.precision(default_precision);
873  output.close();
874  }
875  catch(std::exception& e)
876  {
877  std::cerr<<e.what()<<std::endl;
878  output.close();
879  exit(1);
880  }
881 
882  }
883 
884 
912  template <typename MultiContainer2d>
913  inline
914  void write_tecplot_vect2d(const MultiContainer2d& field,
915  const std::string& file_path_name,
916  const std::string& title,
917  const std::string& zone,
918  const int precision = 6)
919  {
920  std::ofstream output(file_path_name.c_str(),std::ios::out);
921  try
922  {
923  if(!output)
924  {
925  throw std::ios_base::failure(slip::FILE_OPEN_ERROR + file_path_name);
926  }
927  typedef typename MultiContainer2d::block_value_type T;
928  int default_precision = output.precision();
929  output.setf(std::ios::scientific);
930  output.precision(precision);
931  int dim1 = static_cast<int>(field.dim1());
932  int dim2 = static_cast<int>(field.dim2());
933  //write file informations
934  output<<"TITLE=\"" <<title<<"\""<<std::endl;
935  output<<"VARIABLES=\"X\",\"Y\",\"U\",\"V\"" <<std::endl;
936  output<<"ZONE T=\""<<zone<<"\", I="<<dim2<<", J="<<dim1<<std::endl;
937  //write data
938  T y= T(0);
939  for(int i=dim1-1; i >= 0;--i,y+=T(1))
940  {
941  T x= T(0);
942  for(int j=0; j < dim2; ++j,x+=T(1))
943  {
944  output<<static_cast<T>(x)<<" "<<static_cast<T>(y)<<" "<<field[i][j][0]<<" "<<field[i][j][1]<<"\n";
945  }
946  }
947 
948  output.precision(default_precision);
949  output.close();
950  }
951  catch(std::exception& e)
952  {
953  std::cerr<<e.what()<<std::endl;
954  output.close();
955  exit(1);
956  }
957  }
958 
959 
990  template <typename MultiContainer2d, typename T>
991  inline void write_tecplot_vect2d(const MultiContainer2d& field,
992  const slip::Point2d<T>& init_point,
993  const slip::Point2d<T>& step,
994  const std::string& file_path_name,
995  const std::string& title,
996  const std::string& zone,
997  const int precision = 6)
998  {
999  std::ofstream output(file_path_name.c_str(),std::ios::out);
1000  try
1001  {
1002  if(!output)
1003  {
1004  throw std::ios_base::failure(slip::FILE_OPEN_ERROR + file_path_name);
1005  }
1006  // typedef typename MultiContainer2d::block_value_type T;
1007  int default_precision = output.precision();
1008  output.setf(std::ios::scientific);
1009  output.precision(precision);
1010 
1011  int dim1 = static_cast<int>(field.dim1());
1012  int dim2 = static_cast<int>(field.dim2());
1013 
1014  //write file informations
1015  output<<"TITLE=\"" <<title<<"\""<<std::endl;
1016  output<<"VARIABLES=\"X\",\"Y\",\"U\",\"V\"" <<std::endl;
1017  output<<"ZONE T=\""<<zone<<"\", I="<<dim2<<", J="<<dim1<<std::endl;
1018  //write data
1019  T y=init_point[1];
1020  for(int i=dim1-1; i >= 0;--i,y+=step[1])
1021  {
1022  T x=init_point[0];
1023  for(int j=0; j < dim2; ++j,x+=step[0])
1024  {
1025  output<<static_cast<T>(x)<<" "<<static_cast<T>(y)<<" "<<field[i][j][0]<<" "<<field[i][j][1]<<"\n";
1026  }
1027  }
1028 
1029 
1030 
1031  output.precision(default_precision);
1032  output.close();
1033  }
1034  catch(std::exception& e)
1035  {
1036  std::cerr<<e.what()<<std::endl;
1037  output.close();
1038  exit(1);
1039  }
1040  }
1078  template <class MultiContainer2d>
1079  inline
1080  void read_tecplot_vect2d(const std::string& file_path_name,
1081  MultiContainer2d& field)
1082  {
1083  slip::Array2d<double> data;
1084  slip::read_ascii_2d(data,file_path_name);
1085  std::size_t size_y = std::count(data.col_begin(0),data.col_end(0),
1086  data[0][0]);
1087  std::size_t size_x = data.rows() / size_y;
1088 
1089  slip::Point2d<double> init_point;
1090  init_point[0]=std::min(data[0][0],data[data.rows()-1][0]);
1091  init_point[1]=std::min(data[0][1],data[data.rows()-1][1]);
1092  bool y_direct = (init_point[1] == data[0][1]);
1093 
1094  field.resize(size_y,size_x);
1095  if(data[0][0] == data[1][0])
1096  {
1097  //cas x fixe, y varie
1098  std::size_t stepy = 0;
1099 
1100  for(std::size_t j = 0; j < size_x; ++j)
1101  {
1102  if(y_direct)
1103  {
1104  std::copy(data.col_begin(3) + stepy,
1105  data.col_begin(3) + (stepy + size_y),
1106  field.col_rbegin(1,j));
1107  std::copy(data.col_begin(2) + stepy,
1108  data.col_begin(2) + (stepy + size_y),
1109  field.col_rbegin(0,j));
1110  stepy += size_y;
1111  }
1112  else
1113  {
1114  std::copy(data.col_begin(3) + stepy,
1115  data.col_begin(3) + (stepy + size_y),
1116  field.col_begin(1,j));
1117  std::copy(data.col_begin(2) + stepy,
1118  data.col_begin(2) + (stepy + size_y),
1119  field.col_begin(0,j));
1120  stepy += size_y;
1121  }
1122  }
1123  }
1124  else
1125  {
1126  //cas x varie, y fixe
1127  std::size_t stepx = 0;
1128  for(std::size_t j = 0; j < size_y; ++j)
1129  {
1130  if(y_direct)
1131  {
1132  std::copy(data.col_begin(2) + stepx,
1133  data.col_begin(2) + (stepx + size_x),
1134  field.row_begin(0,(size_y - 1) - j));
1135  std::copy(data.col_begin(3) + stepx,
1136  data.col_begin(3) + (stepx + size_x),
1137  field.row_begin(1,(size_y - 1) - j));
1138 
1139  }
1140  else
1141  {
1142  std::copy(data.col_begin(2) + stepx,
1143  data.col_begin(2) + (stepx + size_x),
1144  field.row_begin(0,j));
1145  std::copy(data.col_begin(3) + stepx,
1146  data.col_begin(3) + (stepx + size_x),
1147  field.row_begin(1,j));
1148  }
1149  stepx += size_x;
1150  }
1151  }
1152  }
1153 
1190  template <class MultiContainer2d,typename T>
1191  inline
1192  void read_tecplot_vect2d(const std::string& file_path_name,
1193  MultiContainer2d& field,
1194  slip::Point2d<T>& init_point,
1195  slip::Point2d<T>& step)
1196  {
1197  slip::Array2d<double> data;
1198  slip::read_ascii_2d(data,file_path_name);
1199  std::size_t size_y = std::count(data.col_begin(0),data.col_end(0),
1200  data[0][0]);
1201  std::size_t size_x = data.rows() / size_y;
1202 
1203  init_point[0]=std::min(data[0][0],data[data.rows()-1][0]);
1204  init_point[1]=std::min(data[0][1],data[data.rows()-1][1]);
1205 
1206  bool y_direct = (init_point[1] == data[0][1]);
1207 
1208  field.resize(size_y,size_x);
1209  if(data[0][0] == data[1][0])
1210  {
1211  //cas x fixe, y varie
1212  step[0]=std::abs(*(data.col_begin(0)+size_y)-(*(data.col_begin(0))));
1213  step[1]=std::abs(*(data.col_begin(1)+1)-*(data.col_begin(1)));
1214 
1215  std::size_t stepy = 0;
1216 
1217  for(std::size_t j = 0; j < size_x; ++j)
1218  {
1219  if(y_direct)
1220  {
1221  std::copy(data.col_begin(3) + stepy,
1222  data.col_begin(3) + (stepy + size_y),
1223  field.col_rbegin(1,j));
1224  std::copy(data.col_begin(2) + stepy,
1225  data.col_begin(2) + (stepy + size_y),
1226  field.col_rbegin(0,j));
1227  stepy += size_y;
1228  }
1229  else
1230  {
1231  std::copy(data.col_begin(3) + stepy,
1232  data.col_begin(3) + (stepy + size_y),
1233  field.col_begin(1,j));
1234  std::copy(data.col_begin(2) + stepy,
1235  data.col_begin(2) + (stepy + size_y),
1236  field.col_begin(0,j));
1237  stepy += size_y;
1238  }
1239  }
1240  }
1241  else
1242  {
1243  //cas x varie, y fixe
1244  step[0]=std::abs(*(data.col_begin(0)+1)-(*(data.col_begin(0))));
1245  step[1]=std::abs(*(data.col_begin(1)+size_x) - *(data.col_begin(1)));
1246 
1247  std::size_t stepx = 0;
1248  for(std::size_t j = 0; j < size_y; ++j)
1249  {
1250  if(y_direct)
1251  {
1252  std::copy(data.col_begin(2) + stepx,
1253  data.col_begin(2) + (stepx + size_x),
1254  field.row_begin(0,(size_y - 1) - j));
1255  std::copy(data.col_begin(3) + stepx,
1256  data.col_begin(3) + (stepx + size_x),
1257  field.row_begin(1,(size_y - 1) - j));
1258 
1259  }
1260  else
1261  {
1262  std::copy(data.col_begin(2) + stepx,
1263  data.col_begin(2) + (stepx + size_x),
1264  field.row_begin(0,j));
1265  std::copy(data.col_begin(3) + stepx,
1266  data.col_begin(3) + (stepx + size_x),
1267  field.row_begin(1,j));
1268  }
1269  stepx += size_x;
1270  }
1271  }
1272  }
1273 
1310  template <typename MultiContainer2d>
1311  inline
1312  void read_tecplot_XY(const std::string& file_path_name,
1313  MultiContainer2d& XY)
1314  {
1315  slip::Array2d<double> data;
1316  slip::read_ascii_2d(data,file_path_name);
1317  std::size_t size_y = std::count(data.col_begin(0),data.col_end(0),
1318  data[0][0]);
1319  std::size_t size_x = data.rows() / size_y;
1320 
1321  slip::Point2d<double> init_point;
1322  init_point[0]=std::min(data[0][0],data[data.rows()-1][0]);
1323  init_point[1]=std::min(data[0][1],data[data.rows()-1][1]);
1324  bool y_direct = (init_point[1] == data[0][1]);
1325  XY.resize(size_y,size_x);
1326 
1327  if(data[0][0] == data[1][0])
1328  {
1329  //cas x fixe, y varie
1330  std::size_t stepy = 0;
1331 
1332  for(std::size_t j = 0; j < size_x; ++j)
1333  {
1334  if(y_direct)
1335  {
1336  std::copy(data.col_begin(1) + stepy,
1337  data.col_begin(1) + (stepy + size_y),
1338  XY.col_rbegin(1,j));
1339  std::copy(data.col_begin(0) + stepy,
1340  data.col_begin(0) + (stepy + size_y),
1341  XY.col_rbegin(0,j));
1342  stepy += size_y;
1343  }
1344  else
1345  {
1346  std::copy(data.col_begin(1) + stepy,
1347  data.col_begin(1) + (stepy + size_y),
1348  XY.col_begin(1,j));
1349  std::copy(data.col_begin(0) + stepy,
1350  data.col_begin(0) + (stepy + size_y),
1351  XY.col_begin(0,j));
1352  stepy += size_y;
1353  }
1354  }
1355  }
1356  else
1357  {
1358  //cas x varie, y fixe
1359  std::size_t stepx = 0;
1360  for(std::size_t j = 0; j < size_y; ++j)
1361  {
1362  if(y_direct)
1363  {
1364  std::copy(data.col_begin(0) + stepx,
1365  data.col_begin(0) + (stepx + size_x),
1366  XY.row_begin(0,(size_y - 1) - j));
1367  std::copy(data.col_begin(1) + stepx,
1368  data.col_begin(1) + (stepx + size_x),
1369  XY.row_begin(1,(size_y - 1) - j));
1370 
1371  }
1372  else
1373  {
1374  std::copy(data.col_begin(0) + stepx,
1375  data.col_begin(0) + (stepx + size_x),
1376  XY.row_begin(0,j));
1377  std::copy(data.col_begin(1) + stepx,
1378  data.col_begin(1) + (stepx + size_x),
1379  XY.row_begin(1,j));
1380  }
1381  stepx += size_x;
1382  }
1383  }
1384  }
1385 
1419  template <typename Vector1,
1420  typename Vector2>
1421  inline
1422  void read_tecplot_XY(const std::string& file_path_name,
1423  Vector1& X,
1424  Vector2& Y)
1425  {
1426  typedef typename slip::Array2d<double>::col_iterator col_iterator;
1427  slip::Array2d<double> data;
1428  slip::read_ascii_2d(data,file_path_name);
1429  std::size_t size_y = std::count(data.col_begin(0),data.col_end(0),
1430  data[0][0]);
1431  std::size_t size_x = data.rows() / size_y;
1432  X.resize(size_x);
1433  Y.resize(size_y);
1434 
1435  slip::Point2d<double> init_point;
1436  init_point[0]=std::min(data[0][0],data[data.rows()-1][0]);
1437  init_point[1]=std::min(data[0][1],data[data.rows()-1][1]);
1438  bool y_direct = (init_point[1] == data[0][1]);
1439  if(data[0][0] == data[1][0])
1440  {
1441  //cas x fixe, y varie
1442  if(y_direct)
1443  {
1444  //copy Y
1445  std::copy(data.col_begin(1),data.col_begin(1)+size_y,Y.begin());
1446  //copy X
1448  slip::stride_iterator<col_iterator>(data.col_begin(0),size_y)+size_x,
1449  X.begin());
1450  }
1451  else
1452  {
1453  //copy Y
1454  std::copy(data.col_begin(1),data.col_begin(1)+size_y,Y.rbegin());
1455  //copy X
1457  slip::stride_iterator<col_iterator>(data.col_begin(0),size_y)+size_x,
1458  X.begin());
1459  }
1460  }
1461  else
1462  {
1463  //cas x varie, y fixe
1464  if(y_direct)
1465  {
1466  //copy X
1467  std::copy(data.col_begin(0),data.col_begin(0)+size_x,X.begin());
1468  //copy Y
1470  slip::stride_iterator<col_iterator>(data.col_begin(1),size_x)+size_y,
1471  Y.begin());
1472  }
1473  else
1474  {
1475  //copy X
1476  std::copy(data.col_begin(0),data.col_begin(0)+size_x,X.begin());
1477  //copy Y
1479  slip::stride_iterator<col_iterator>(data.col_begin(1),size_x)+size_y,
1480  Y.rbegin());
1481  }
1482  }
1483 
1484  }
1485 
1519  template <class MultiContainer2d>
1520  inline
1521  void read_gnuplot_vect2d(const std::string& file_path_name,
1522  MultiContainer2d& field)
1523  {
1524  slip::read_tecplot_vect2d(file_path_name,field);
1525  }
1526 
1561  template <class MultiContainer2d,typename T>
1562  inline
1563  void read_gnuplot_vect2d(const std::string& file_path_name,
1564  MultiContainer2d& field,
1565  slip::Point2d<T>& init_point,
1566  slip::Point2d<T>& step)
1567  {
1568  slip::read_tecplot_vect2d(file_path_name,field,init_point,step);
1569  }
1570 
1602  template <typename MultiContainer2d>
1603  inline
1604  void read_gnuplot_XY(const std::string& file_path_name,
1605  MultiContainer2d& XY)
1606  {
1607  slip::read_tecplot_XY(file_path_name,XY);
1608  }
1609 
1610 
1639  template <typename Vector1,
1640  typename Vector2>
1641  inline
1642  void read_gnuplot_XY(const std::string& file_path_name,
1643  Vector1& X,
1644  Vector2& Y)
1645  {
1646  slip::read_tecplot_XY(file_path_name,X,Y);
1647  }
1648 
1649 
1650 
1651 
1652 /* @} */
1653 
1655  /* @{ */
1656 
1683  template <typename DenseVector3dField3d>
1684  inline
1686  const std::string& file_path_name,
1687  const std::string& title,
1688  const std::string& zone,
1689  const int precision = 6)
1690  {
1691  std::ofstream output(file_path_name.c_str(),std::ios::out);
1692  try
1693  {
1694  if(!output)
1695  {
1696  throw std::ios_base::failure(slip::FILE_OPEN_ERROR + file_path_name);
1697  }
1698 
1699  typedef typename DenseVector3dField3d::block_value_type T;
1700  int default_precision = output.precision();
1701  output.setf(std::ios::scientific);
1702  output.precision(precision);
1703  int dim1 = static_cast<int>(field.dim1()); //z
1704  int dim2 = static_cast<int>(field.dim2()); //y
1705  int dim3 = static_cast<int>(field.dim3());//x
1706 
1707  //write file informations
1708  output<<"TITLE=\"" <<title<<"\""<<std::endl;
1709  output<<"VARIABLES=\"X\",\"Y\",\"Z\",\"U\",\"V\",\"W\"" <<std::endl;
1710  output<<"ZONE T=\""<<zone<<"\", I="<<dim3<<", J="<<dim2<<", K="<<dim1<<std::endl;
1711  //write data
1712  T z = T(0);
1713  for(int k = dim1-1; k >= 0;--k,z+=T(1))
1714  {
1715  T y = T(0);
1716  for(int i = dim2-1; i >= 0;--i,y+=T(1))
1717  {
1718  T x = T(0);
1719  for(int j = 0; j < dim3; ++j,x+=T(1))
1720  {
1721  output<<static_cast<T>(x)<<" "<<static_cast<T>(y)<<" "<<static_cast<T>(z)<<" "<<field[k][i][j][0]<<" "<<field[k][i][j][1]<<" "<<field[k][i][j][2]<<"\n";
1722  }
1723  }
1724  }
1725  output.precision(default_precision);
1726  output.close();
1727  }
1728  catch(std::exception& e)
1729  {
1730  std::cerr<<e.what()<<std::endl;
1731  output.close();
1732  exit(1);
1733  }
1734  }
1735 
1736 
1767  template <typename DenseVector3dField3d,typename T>
1768  inline
1770  const slip::Point3d<T>& init_point,
1771  const slip::Point3d<T>& step,
1772  const std::string& file_path_name,
1773  const std::string& title,
1774  const std::string& zone,
1775  const int precision = 6)
1776  {
1777 
1778  std::ofstream output(file_path_name.c_str(),std::ios::out);
1779  try
1780  {
1781  if(!output)
1782  {
1783  throw std::ios_base::failure(slip::FILE_OPEN_ERROR + file_path_name);
1784  }
1785 
1786  int default_precision = output.precision();
1787  output.setf(std::ios::scientific);
1788  output.precision(precision);
1789  int dim1 = static_cast<int>(field.dim1()); //z
1790  int dim2 = static_cast<int>(field.dim2()); //y
1791  int dim3 = static_cast<int>(field.dim3());//x
1792 
1793  //write file informations
1794  output<<"TITLE=\"" <<title<<"\""<<std::endl;
1795  output<<"VARIABLES=\"X\",\"Y\",\"Z\",\"U\",\"V\",\"W\"" <<std::endl;
1796  output<<"ZONE T=\""<<zone<<"\", I="<<dim3<<", J="<<dim2<<", K="<<dim1<<std::endl;
1797  //write data
1798  T z = init_point[2];
1799  for(int k = dim1-1; k >= 0;--k,z+=step[2])
1800  {
1801  T y = init_point[1];
1802  for(int i = dim2-1; i >= 0;--i,y+=step[1])
1803  {
1804  T x = init_point[0];
1805  for(int j = 0; j < dim3; ++j,x+=step[0])
1806  {
1807  output<<static_cast<T>(x)<<" "<<static_cast<T>(y)<<" "<<static_cast<T>(z)<<" "<<field[k][i][j][0]<<" "<<field[k][i][j][1]<<" "<<field[k][i][j][2]<<"\n";
1808  }
1809  }
1810  }
1811 
1812  output.precision(default_precision);
1813  output.close();
1814  }
1815  catch(std::exception& e)
1816  {
1817  std::cerr<<e.what()<<std::endl;
1818  output.close();
1819  exit(1);
1820  }
1821  }
1858  template <class MultiContainer3d>
1859  inline
1860  void read_tecplot_vect3d(const std::string& file_path_name,
1861  MultiContainer3d& field)
1862  {
1863  slip::Array2d<double> data;
1864  slip::read_ascii_2d(data,file_path_name);
1865  std::size_t size = data.rows();
1866  std::size_t size_xy = std::count(data.col_begin(2),data.col_end(2),data[0][2]);
1867  std::size_t size_z = size / size_xy;
1868  std::size_t size_y = std::count(data.col_begin(0),data.col_end(0),data[0][0]);
1869  size_y = size_y / size_z;
1870  std::size_t size_x = size / (size_y * size_z);
1871 
1872  slip::Point3d<double> init_point;
1873  init_point[0]=std::min(data[0][0],data[data.rows()-1][0]);
1874  init_point[1]=std::min(data[0][1],data[data.rows()-1][1]);
1875  init_point[2]=std::min(data[0][2],data[data.rows()-1][2]);
1876 
1877 
1878  bool y_direct = (init_point[1] == data[0][1]);
1879 
1880  field.resize(size_z,size_y,size_x);
1881 
1882  if(data[0][0] == data[1][0])
1883  {
1884  //cas x fixe, y varie
1885 
1886  std::size_t stepz = 0;
1887  for(std::size_t k = 0 ; k < size_z; ++k)
1888  {
1889  std::size_t stepy = 0;
1890 
1891  for(std::size_t j = 0; j < size_x; ++j)
1892  {
1893  if(y_direct)
1894  {
1895  std::copy(data.col_begin(4) + stepz + stepy,
1896  data.col_begin(4) + (stepz + stepy + size_y),
1897  field.col_rbegin(1,(size_z-1)-k,j));
1898  std::copy(data.col_begin(3) + stepz + stepy,
1899  data.col_begin(3) + (stepz + stepy + size_y),
1900  field.col_rbegin(0,(size_z-1)-k,j));
1901  std::copy(data.col_begin(5) + stepz + stepy,
1902  data.col_begin(5) + (stepz + stepy + size_y),
1903  field.col_rbegin(2,(size_z-1)-k,j));
1904  stepy += size_y;
1905  }
1906  else
1907  {
1908  std::copy(data.col_begin(4) + stepz + stepy,
1909  data.col_begin(4) + (stepz + stepy + size_y),
1910  field.col_begin(1,(size_z-1)-k,j));
1911  std::copy(data.col_begin(3) + stepz + stepy,
1912  data.col_begin(3) + (stepz + stepy + size_y),
1913  field.col_begin(0,(size_z-1)-k,j));
1914  std::copy(data.col_begin(5) + stepz + stepy,
1915  data.col_begin(5) + (stepz + stepy + size_y),
1916  field.col_begin(2,(size_z-1)-k,j));
1917  stepy += size_y;
1918  }
1919  }
1920  stepz+=size_xy;
1921  }
1922  }
1923  else
1924  {
1925  //cas x varie, y fixe
1926  std::size_t stepz = 0;
1927  for(std::size_t k = 0 ; k < size_z; ++k)
1928  {
1929  std::size_t stepx = 0;
1930  for(std::size_t j = 0; j < size_y; ++j)
1931  {
1932  if(y_direct)
1933  {
1934  std::copy(data.col_begin(3) + stepz + stepx,
1935  data.col_begin(3) + (stepz + stepx + size_x),
1936  field.row_begin(0,(size_z-1)-k,(size_y - 1) - j));
1937  std::copy(data.col_begin(4) + stepz + stepx,
1938  data.col_begin(4) + (stepz + stepx + size_x),
1939  field.row_begin(1,(size_z-1)-k,(size_y - 1) - j));
1940  std::copy(data.col_begin(5) + stepz + stepx,
1941  data.col_begin(5) + (stepz + stepx + size_x),
1942  field.row_begin(2,(size_z-1)-k,(size_y - 1) - j));
1943 
1944  }
1945  else
1946  {
1947  std::copy(data.col_begin(3) + stepz + stepx,
1948  data.col_begin(3) + stepz + (stepx + size_x),
1949  field.row_begin(0,(size_z-1)-k,j));
1950  std::copy(data.col_begin(4) + stepz + stepx,
1951  data.col_begin(4) + (stepz + stepx + size_x),
1952  field.row_begin(1,(size_z-1)-k,j));
1953  std::copy(data.col_begin(5) + stepz + stepx,
1954  data.col_begin(5) + (stepz + stepx + size_x),
1955  field.row_begin(2,(size_z-1)-k,j));
1956  }
1957  stepx += size_x;
1958  }
1959  stepz+=size_xy;
1960  }
1961  }
1962  }
1963 
1998  template <class MultiContainer3d,typename T>
1999  inline
2000  void read_tecplot_vect3d(const std::string& file_path_name,
2001  MultiContainer3d& field,
2002  slip::Point3d<T>& init_point,
2003  slip::Point3d<T>& step)
2004  {
2005 
2006  slip::Array2d<double> data;
2007  slip::read_ascii_2d(data,file_path_name);
2008  std::size_t size = data.rows();
2009  std::size_t size_xy = std::count(data.col_begin(2),data.col_end(2),data[0][2]);
2010  std::size_t size_z = size / size_xy;
2011  std::size_t size_y = std::count(data.col_begin(0),data.col_end(0),data[0][0]);
2012  size_y = size_y / size_z;
2013  std::size_t size_x = size / (size_y * size_z);
2014 
2015 
2016  init_point[0]=std::min(data[0][0],data[data.rows()-1][0]);
2017  init_point[1]=std::min(data[0][1],data[data.rows()-1][1]);
2018  init_point[2]=std::min(data[0][2],data[data.rows()-1][2]);
2019 
2020 
2021  bool y_direct = (init_point[1] == data[0][1]);
2022 
2023  field.resize(size_z,size_y,size_x);
2024 
2025  if(data[0][0] == data[1][0])
2026  {
2027  //cas x fixe, y varie
2028  step[0]=std::abs(*(data.col_begin(0)+size_y)-(*(data.col_begin(0))));
2029  step[1]=std::abs(*(data.col_begin(1)+1)-*(data.col_begin(1)));
2030  step[2]=std::abs(*(data.col_begin(2)+size_xy)-*(data.col_begin(2)));
2031  std::size_t stepz = 0;
2032  for(std::size_t k = 0 ; k < size_z; ++k)
2033  {
2034  std::size_t stepy = 0;
2035 
2036  for(std::size_t j = 0; j < size_x; ++j)
2037  {
2038  if(y_direct)
2039  {
2040  std::copy(data.col_begin(4) + stepz + stepy,
2041  data.col_begin(4) + (stepz + stepy + size_y),
2042  field.col_rbegin(1,(size_z-1)-k,j));
2043  std::copy(data.col_begin(3) + stepz + stepy,
2044  data.col_begin(3) + (stepz + stepy + size_y),
2045  field.col_rbegin(0,(size_z-1)-k,j));
2046  std::copy(data.col_begin(5) + stepz + stepy,
2047  data.col_begin(5) + (stepz + stepy + size_y),
2048  field.col_rbegin(2,(size_z-1)-k,j));
2049  stepy += size_y;
2050  }
2051  else
2052  {
2053  std::copy(data.col_begin(4) + stepz + stepy,
2054  data.col_begin(4) + (stepz + stepy + size_y),
2055  field.col_begin(1,(size_z-1)-k,j));
2056  std::copy(data.col_begin(3) + stepz + stepy,
2057  data.col_begin(3) + (stepz + stepy + size_y),
2058  field.col_begin(0,(size_z-1)-k,j));
2059  std::copy(data.col_begin(5) + stepz + stepy,
2060  data.col_begin(5) + (stepz + stepy + size_y),
2061  field.col_begin(2,(size_z-1)-k,j));
2062  stepy += size_y;
2063  }
2064  }
2065  stepz+=size_xy;
2066  }
2067  }
2068  else
2069  {
2070  //cas x varie, y fixe
2071  step[0]=std::abs(*(data.col_begin(0)+1)-(*(data.col_begin(0))));
2072  step[1]=std::abs(*(data.col_begin(1)+size_x) - *(data.col_begin(1)));
2073  step[2]=std::abs(*(data.col_begin(2)+size_xy) - *(data.col_begin(2)));
2074 
2075  std::size_t stepz = 0;
2076  for(std::size_t k = 0 ; k < size_z; ++k)
2077  {
2078  std::size_t stepx = 0;
2079  for(std::size_t j = 0; j < size_y; ++j)
2080  {
2081  if(y_direct)
2082  {
2083  std::copy(data.col_begin(3) + stepz + stepx,
2084  data.col_begin(3) + (stepz + stepx + size_x),
2085  field.row_begin(0,(size_z-1)-k,(size_y - 1) - j));
2086  std::copy(data.col_begin(4) + stepz + stepx,
2087  data.col_begin(4) + (stepz + stepx + size_x),
2088  field.row_begin(1,(size_z-1)-k,(size_y - 1) - j));
2089  std::copy(data.col_begin(5) + stepz + stepx,
2090  data.col_begin(5) + (stepz + stepx + size_x),
2091  field.row_begin(2,(size_z-1)-k,(size_y - 1) - j));
2092 
2093  }
2094  else
2095  {
2096  std::copy(data.col_begin(3) + stepz + stepx,
2097  data.col_begin(3) + stepz + (stepx + size_x),
2098  field.row_begin(0,(size_z-1)-k,j));
2099  std::copy(data.col_begin(4) + stepz + stepx,
2100  data.col_begin(4) + (stepz + stepx + size_x),
2101  field.row_begin(1,(size_z-1)-k,j));
2102  std::copy(data.col_begin(5) + stepz + stepx,
2103  data.col_begin(5) + (stepz + stepx + size_x),
2104  field.row_begin(2,(size_z-1)-k,j));
2105  }
2106  stepx += size_x;
2107  }
2108  stepz+=size_xy;
2109  }
2110  }
2111 
2112 
2113  }
2114 
2151  template <class MultiContainer3d>
2152  inline
2153  void read_tecplot_XYZ(const std::string& file_path_name,
2154  MultiContainer3d& XYZ)
2155  {
2156  slip::Array2d<double> data;
2157  slip::read_ascii_2d(data,file_path_name);
2158  std::size_t size = data.rows();
2159  std::size_t size_xy = std::count(data.col_begin(2),data.col_end(2),data[0][2]);
2160  std::size_t size_z = size / size_xy;
2161  std::size_t size_y = std::count(data.col_begin(0),data.col_end(0),data[0][0]);
2162  size_y = size_y / size_z;
2163  std::size_t size_x = size / (size_y * size_z);
2164 
2165  slip::Point3d<double> init_point;
2166  init_point[0]=std::min(data[0][0],data[data.rows()-1][0]);
2167  init_point[1]=std::min(data[0][1],data[data.rows()-1][1]);
2168  init_point[2]=std::min(data[0][2],data[data.rows()-1][2]);
2169 
2170 
2171  bool y_direct = (init_point[1] == data[0][1]);
2172 
2173  XYZ.resize(size_z,size_y,size_x);
2174 
2175  if(data[0][0] == data[1][0])
2176  {
2177  //cas x fixe, y varie
2178 
2179  std::size_t stepz = 0;
2180  for(std::size_t k = 0 ; k < size_z; ++k)
2181  {
2182  std::size_t stepy = 0;
2183 
2184  for(std::size_t j = 0; j < size_x; ++j)
2185  {
2186  if(y_direct)
2187  {
2188  std::copy(data.col_begin(1) + stepz + stepy,
2189  data.col_begin(1) + (stepz + stepy + size_y),
2190  XYZ.col_rbegin(1,(size_z-1)-k,j));
2191  std::copy(data.col_begin(0) + stepz + stepy,
2192  data.col_begin(0) + (stepz + stepy + size_y),
2193  XYZ.col_rbegin(0,(size_z-1)-k,j));
2194  std::copy(data.col_begin(2) + stepz + stepy,
2195  data.col_begin(2) + (stepz + stepy + size_y),
2196  XYZ.col_rbegin(2,(size_z-1)-k,j));
2197  stepy += size_y;
2198  }
2199  else
2200  {
2201  std::copy(data.col_begin(1) + stepz + stepy,
2202  data.col_begin(1) + (stepz + stepy + size_y),
2203  XYZ.col_begin(1,(size_z-1)-k,j));
2204  std::copy(data.col_begin(0) + stepz + stepy,
2205  data.col_begin(0) + (stepz + stepy + size_y),
2206  XYZ.col_begin(0,(size_z-1)-k,j));
2207  std::copy(data.col_begin(2) + stepz + stepy,
2208  data.col_begin(2) + (stepz + stepy + size_y),
2209  XYZ.col_begin(2,(size_z-1)-k,j));
2210  stepy += size_y;
2211  }
2212  }
2213  stepz+=size_xy;
2214  }
2215  }
2216  else
2217  {
2218  //cas x varie, y fixe
2219  std::size_t stepz = 0;
2220  for(std::size_t k = 0 ; k < size_z; ++k)
2221  {
2222  std::size_t stepx = 0;
2223  for(std::size_t j = 0; j < size_y; ++j)
2224  {
2225  if(y_direct)
2226  {
2227  std::copy(data.col_begin(0) + stepz + stepx,
2228  data.col_begin(0) + (stepz + stepx + size_x),
2229  XYZ.row_begin(0,(size_z-1)-k,(size_y - 1) - j));
2230  std::copy(data.col_begin(1) + stepz + stepx,
2231  data.col_begin(1) + (stepz + stepx + size_x),
2232  XYZ.row_begin(1,(size_z-1)-k,(size_y - 1) - j));
2233  std::copy(data.col_begin(2) + stepz + stepx,
2234  data.col_begin(2) + (stepz + stepx + size_x),
2235  XYZ.row_begin(2,(size_z-1)-k,(size_y - 1) - j));
2236 
2237  }
2238  else
2239  {
2240  std::copy(data.col_begin(0) + stepz + stepx,
2241  data.col_begin(0) + stepz + (stepx + size_x),
2242  XYZ.row_begin(0,(size_z-1)-k,j));
2243  std::copy(data.col_begin(1) + stepz + stepx,
2244  data.col_begin(1) + (stepz + stepx + size_x),
2245  XYZ.row_begin(1,(size_z-1)-k,j));
2246  std::copy(data.col_begin(2) + stepz + stepx,
2247  data.col_begin(2) + (stepz + stepx + size_x),
2248  XYZ.row_begin(2,(size_z-1)-k,j));
2249  }
2250  stepx += size_x;
2251  }
2252  stepz+=size_xy;
2253  }
2254  }
2255  }
2256 
2293  template <class Vector1, class Vector2, class Vector3>
2294  inline
2295  void read_tecplot_XYZ(const std::string& file_path_name,
2296  Vector1& X,
2297  Vector2& Y,
2298  Vector3& Z)
2299  {
2300 
2301  typedef typename slip::Array2d<double>::col_iterator col_iterator;
2302  slip::Array2d<double> data;
2303  slip::read_ascii_2d(data,file_path_name);
2304  std::size_t size = data.rows();
2305  std::size_t size_xy = std::count(data.col_begin(2),data.col_end(2),data[0][2]);
2306  std::size_t size_z = size / size_xy;
2307  std::size_t size_y = std::count(data.col_begin(0),data.col_end(0),data[0][0]);
2308  size_y = size_y / size_z;
2309  std::size_t size_x = size / (size_y * size_z);
2310 
2311  slip::Point3d<double> init_point;
2312  init_point[0]=std::min(data[0][0],data[data.rows()-1][0]);
2313  init_point[1]=std::min(data[0][1],data[data.rows()-1][1]);
2314  init_point[2]=std::min(data[0][2],data[data.rows()-1][2]);
2315 
2316 
2317  bool y_direct = (init_point[1] == data[0][1]);
2318 
2319  X.resize(size_x);
2320  Y.resize(size_y);
2321  Z.resize(size_z);
2322 
2323 
2324  if(data[0][0] == data[1][0])
2325  {
2326 
2327  //cas x fixe, y varie
2328  if(y_direct)
2329  {
2330  //copy Y
2331  std::copy(data.col_begin(1),data.col_begin(1)+size_y,Y.begin());
2332  //copy X
2334  slip::stride_iterator<col_iterator>(data.col_begin(0),size_y) +size_x,
2335  X.begin());
2336  //copy Z
2338  slip::stride_iterator<col_iterator>(data.col_begin(2),size_xy) + size_z,
2339  Z.begin());
2340 
2341  }
2342  else
2343  {
2344  //copy Y
2345  std::copy(data.col_begin(1),data.col_begin(1)+size_y,Y.rbegin());
2346  //copy X
2348  slip::stride_iterator<col_iterator>(data.col_begin(0),size_y) +size_x,
2349  X.begin());
2350  //copy Z
2352  slip::stride_iterator<col_iterator>(data.col_begin(2),size_xy) + size_z,
2353  Z.begin());
2354 
2355  }
2356 
2357 
2358 
2359 
2360  }
2361  else
2362  {
2363  //cas x varie, y fixe
2364  if(y_direct)
2365  {
2366  //copy X
2367  std::copy(data.col_begin(0),data.col_begin(0)+size_x,X.begin());
2368  //copy Y
2370  slip::stride_iterator<col_iterator>(data.col_begin(1),size_x) +size_y,
2371  Y.begin());
2372  //copy Z
2374  slip::stride_iterator<col_iterator>(data.col_begin(2),size_xy) + size_z,
2375  Z.begin());
2376  }
2377  else
2378  {
2379  //copy X
2380  std::copy(data.col_begin(0),data.col_begin(0)+size_x,X.begin());
2381  //copy Y
2383  slip::stride_iterator<col_iterator>(data.col_begin(1),size_x) +size_y,
2384  Y.rbegin());
2385  //copy Z
2387  slip::stride_iterator<col_iterator>(data.col_begin(2),size_xy) + size_z,
2388  Z.begin());
2389  }
2390 
2391 
2392  }
2393 
2394  }
2395 
2396 
2397 
2398 
2399 
2435  template <class MultiContainer3d>
2436  inline
2437  void read_gnuplot_XYZ(const std::string& file_path_name,
2438  MultiContainer3d& XYZ)
2439  {
2440  slip::read_tecplot_XYZ(file_path_name,XYZ);
2441  }
2442 
2443 /* @} */
2444 
2445 
2446 
2447 
2448 
2449 
2451  /* @{ */
2452 
2473  template <typename InputIterator, typename WriteType>
2474  inline
2475  void write_ascii_1d(InputIterator first,
2476  InputIterator last,
2477  const std::string& file_path_name)
2478  {
2479  std::ofstream output(file_path_name.c_str(),std::ios::out);
2480  try
2481  {
2482  if(!output)
2483  {
2484  throw std::ios_base::failure(slip::FILE_OPEN_ERROR + file_path_name); }
2485 
2486  std::copy(first,last,std::ostream_iterator<WriteType>(output,"\n"));
2487  output.close();
2488  }
2489  catch(std::exception& e)
2490  {
2491  std::cerr<<e.what()<<std::endl;
2492  output.close();
2493  exit(1);
2494  }
2495 
2496  }
2497 
2516  template <typename Container1d>
2517  inline
2518  void read_ascii_1d(const std::string& file_path_name,
2519  Container1d& container)
2520  {
2521  std::ifstream input;
2522 
2523  try
2524  {
2525  input.open(file_path_name.c_str());
2526  if(!input)
2527  {
2528  throw std::ios_base::failure(slip::FILE_OPEN_ERROR + file_path_name);
2529  }
2530 
2531  //computes the number of rows
2532  int nr = 0;
2533  std::string line;
2534  while ( std::getline(input, line ) && line.length()!=0)
2535  {
2536  ++nr;
2537  }
2538 
2539  input.close();
2540  container.resize((std::size_t)nr);
2541  input.open(file_path_name.c_str());
2542  if(!input)
2543  {
2544  throw std::ios_base::failure(slip::FILE_OPEN_ERROR + file_path_name);
2545  }
2546 
2547  //reading datas
2548  for(std::size_t i = 0; i < container.size(); ++i)
2549  {
2550  typename Container1d::value_type tmp;
2551  input>>tmp;
2552  container[i] = tmp;
2553  }
2554  input.close();
2555 
2556  }
2557  catch(std::exception& e)
2558  {
2559  std::cerr<<e.what()<<std::endl;
2560  input.close();
2561  exit(1);
2562  }
2563 
2564  }
2565 /* @} */
2566 
2568  /* @{ */
2569 
2570  #ifdef HAVE_MAGICK
2571 
2584  template<typename RandomAccessIterator>
2585  inline
2586  void write_magick_gray(RandomAccessIterator first,
2587  const std::size_t w,
2588  const std::size_t h,
2589  const StorageType storage_t,
2590  const std::string& file_path_name)
2591  {
2592  //Create the wand
2593  MagickWandGenesis();
2594  MagickWand* wand = NewMagickWand();
2595 
2596  //Write the image located at file_path_name
2597  MagickSetImageColorspace(wand,GRAYColorspace);
2598  unsigned long width = (unsigned long)w;
2599  unsigned long height = (unsigned long)h;
2600  MagickConstituteImage(wand,width,height,"I",storage_t,first);
2601  MagickBooleanType status = MagickWriteImage(wand,file_path_name.c_str());
2602  if(status == MagickFalse)
2603  {
2604  ThrowWandException(wand);
2605  }
2606  wand = DestroyMagickWand(wand);
2607  MagickWandTerminus();
2608  }
2609 
2621  template<typename RandomAccessIterator>
2622  inline
2623  void write_magick_gray_char(RandomAccessIterator first,
2624  const std::size_t w,
2625  const std::size_t h,
2626  const std::string& file_path_name)
2627  {
2628  slip::write_magick_gray(first,w,h,CharPixel,file_path_name);
2629  }
2630 
2643  template<typename RandomAccessIterator>
2644  inline
2645  void write_magick_gray_short(RandomAccessIterator first,
2646  const std::size_t w,
2647  const std::size_t h,
2648  const std::string& file_path_name)
2649  {
2650  slip::write_magick_gray(first,w,h,ShortPixel,file_path_name);
2651  }
2652 
2653 
2666  template<typename RandomAccessIterator>
2667  inline
2668  void write_magick_gray_int(RandomAccessIterator first,
2669  const std::size_t w,
2670  const std::size_t h,
2671  const std::string& file_path_name)
2672  {
2673  slip::write_magick_gray(first,w,h,IntegerPixel,file_path_name);
2674  }
2675 
2686  template<typename RandomAccessIterator>
2687  inline
2688  void write_magick_gray_long(RandomAccessIterator first,
2689  const std::size_t w,
2690  const std::size_t h,
2691  const std::string& file_path_name)
2692  {
2693  slip::write_magick_gray(first,w,h,LongPixel,file_path_name);
2694  }
2695 
2708  template<typename RandomAccessIterator>
2709  inline
2710  void write_magick_gray_float(RandomAccessIterator first,
2711  const std::size_t w,
2712  const std::size_t h,
2713  const std::string& file_path_name)
2714  {
2715  slip::write_magick_gray(first,w,h,FloatPixel,file_path_name);
2716  }
2717 
2729  template<typename RandomAccessIterator>
2730  inline
2731  void write_magick_gray_double(RandomAccessIterator first,
2732  const std::size_t w,
2733  const std::size_t h,
2734  const std::string& file_path_name)
2735  {
2736  slip::write_magick_gray(first,w,h,DoublePixel,file_path_name);
2737  }
2738 
2739 
2753  template<typename RandomAccessIterator2d>
2754  inline
2755  void write_magick_gray(RandomAccessIterator2d upper_left,
2756  RandomAccessIterator2d bottom_right,
2757  const StorageType storage_t,
2758  const std::string& file_path_name)
2759  {
2760 
2761  typename RandomAccessIterator2d::difference_type size2d
2762  = bottom_right - upper_left;
2763 
2764  slip::Array<typename RandomAccessIterator2d::value_type> array(size2d[0] * size2d[1]);
2765  array.fill(upper_left,bottom_right);
2766  slip::write_magick_gray(array.begin(),
2767  (std::size_t)size2d[1],
2768  (std::size_t)size2d[0],
2769  storage_t,
2770  file_path_name);
2771  }
2772 
2773 
2785  template<typename RandomAccessIterator2d>
2786  inline
2787  void write_magick_gray_char(RandomAccessIterator2d upper_left,
2788  RandomAccessIterator2d bottom_right,
2789  const std::string& file_path_name)
2790  {
2791  slip::write_magick_gray(upper_left,bottom_right,CharPixel,file_path_name);
2792  }
2793 
2805  template<typename RandomAccessIterator2d>
2806  inline
2807  void write_magick_gray_short(RandomAccessIterator2d upper_left,
2808  RandomAccessIterator2d bottom_right,
2809  const std::string& file_path_name)
2810  {
2811  slip::write_magick_gray(upper_left,bottom_right,ShortPixel,file_path_name);
2812  }
2813 
2825  template<typename RandomAccessIterator2d>
2826  inline
2827  void write_magick_gray_int(RandomAccessIterator2d upper_left,
2828  RandomAccessIterator2d bottom_right,
2829  const std::string& file_path_name)
2830  {
2831  slip::write_magick_gray(upper_left,bottom_right,IntegerPixel,file_path_name);
2832  }
2833 
2845  template<typename RandomAccessIterator2d>
2846  inline
2847  void write_magick_gray_long(RandomAccessIterator2d upper_left,
2848  RandomAccessIterator2d bottom_right,
2849  const std::string& file_path_name)
2850  {
2851  slip::write_magick_gray(upper_left,bottom_right,LongPixel,file_path_name);
2852  }
2853 
2865  template<typename RandomAccessIterator2d>
2866  inline
2867  void write_magick_gray_float(RandomAccessIterator2d upper_left,
2868  RandomAccessIterator2d bottom_right,
2869  const std::string& file_path_name)
2870  {
2871  slip::write_magick_gray(upper_left,bottom_right,FloatPixel,file_path_name);
2872  }
2873 
2885  template<typename RandomAccessIterator2d>
2886  inline
2887  void write_magick_gray_double(RandomAccessIterator2d upper_left,
2888  RandomAccessIterator2d bottom_right,
2889  const std::string& file_path_name)
2890  {
2891  slip::write_magick_gray(upper_left,bottom_right,DoublePixel,file_path_name);
2892  }
2893 
2894 
2907  template<typename Container2d>
2908  inline
2909  void read_magick_gray(const std::string& file_path_name,
2910  Container2d& container,
2911  const StorageType storage_t)
2912  {
2913  //Create the wand
2914  MagickWandGenesis();
2915  MagickWand* wand = NewMagickWand();
2916  //Read the image located at file_path_name
2917  MagickBooleanType status= MagickReadImage(wand,file_path_name.c_str());
2918  if (status == MagickFalse)
2919  {
2920  ThrowWandException(wand);
2921  }
2922  unsigned long width = MagickGetImageWidth(wand);
2923  unsigned long height = MagickGetImageHeight(wand);
2924  container.resize(std::size_t(height),
2925  std::size_t(width),
2926  0);
2927  // // In 6.4.5.4 MagickGetImagePixels changed to MagickGetAuthenticPixels
2928 // #if MagickLibVersion == 0x645
2929 // #define MagickGetImagePixels MagickGetAuthenticPixels
2930 // #endif
2931  // In 6.4.6 MagickGetImagePixels changed to MagickExportImagePixels
2932  #if MagickLibVersion >= 0x646
2933  #define MagickGetImagePixels MagickExportImagePixels
2934  #endif
2935 
2936  MagickGetImagePixels(wand,0,0,width,height,"I",storage_t,container.begin());
2937 
2938  wand = DestroyMagickWand(wand);
2939  MagickWandTerminus();
2940  }
2941 
2952  template<typename Container2d>
2953  inline
2954  void read_magick_gray_char(const std::string& file_path_name,
2955  Container2d& container)
2956  {
2957  read_magick_gray(file_path_name,container,CharPixel);
2958  }
2959 
2970  template<typename Container2d>
2971  inline
2972  void read_magick_gray_short(const std::string& file_path_name,
2973  Container2d& container)
2974  {
2975  read_magick_gray(file_path_name,container,ShortPixel);
2976  }
2977 
2988  template<typename Container2d>
2989  inline
2990  void read_magick_gray_int(const std::string& file_path_name,
2991  Container2d& container)
2992  {
2993  read_magick_gray(file_path_name,container,IntegerPixel);
2994  }
2995 
3006  template<typename Container2d>
3007  inline
3008  void read_magick_gray_long(const std::string& file_path_name,
3009  Container2d& container)
3010  {
3011  read_magick_gray(file_path_name,container,LongPixel);
3012  }
3013 
3024  template<typename Container2d>
3025  inline
3026  void read_magick_gray_float(const std::string& file_path_name,
3027  Container2d& container)
3028  {
3029  read_magick_gray(file_path_name,container,FloatPixel);
3030  }
3031 
3042  template<typename Container2d>
3043  inline
3044  void read_magick_gray_double(const std::string& file_path_name,
3045  Container2d& container)
3046  {
3047  read_magick_gray(file_path_name,container,DoublePixel);
3048  }
3049 
3050  /* @} */
3051 
3053  /* @{ */
3067  template<typename RandomAccessIterator>
3068  inline
3069  void write_magick_color_char(RandomAccessIterator first,
3070  const std::size_t w,
3071  const std::size_t h,
3072  const std::string& file_path_name)
3073  {
3074  //Create the wand
3075  MagickWandGenesis();
3076  MagickWand* wand = NewMagickWand();
3077 
3078  //Write the image located at file_path_name
3079  MagickSetImageColorspace(wand,RGBColorspace);
3080  unsigned long width = (unsigned long)w;
3081  unsigned long height = (unsigned long)h;
3082  MagickConstituteImage(wand,width,height,"RGB",CharPixel,(unsigned char*)first);
3083  MagickBooleanType status = MagickWriteImage(wand,file_path_name.c_str());
3084  if(status == MagickFalse)
3085  {
3086  ThrowWandException(wand);
3087  }
3088  wand = DestroyMagickWand(wand);
3089  MagickWandTerminus();
3090  }
3091 
3105  template<typename RandomAccessIterator>
3106  inline
3107  void write_magick_color_short(RandomAccessIterator first,
3108  const std::size_t w,
3109  const std::size_t h,
3110  const std::string& file_path_name)
3111  {
3112  //Create the wand
3113  MagickWandGenesis();
3114  MagickWand* wand = NewMagickWand();
3115 
3116  //Write the image located at file_path_name
3117  MagickSetImageColorspace(wand,RGBColorspace);
3118  unsigned long width = (unsigned long)w;
3119  unsigned long height = (unsigned long)h;
3120  MagickConstituteImage(wand,width,height,"RGB",ShortPixel,(short*)first);
3121  MagickBooleanType status = MagickWriteImage(wand,file_path_name.c_str());
3122  if(status == MagickFalse)
3123  {
3124  ThrowWandException(wand);
3125  }
3126  wand = DestroyMagickWand(wand);
3127  MagickWandTerminus();
3128  }
3129 
3143  template<typename RandomAccessIterator>
3144  inline
3145  void write_magick_color_int(RandomAccessIterator first,
3146  const std::size_t w,
3147  const std::size_t h,
3148  const std::string& file_path_name)
3149  {
3150  //Create the wand
3151  MagickWandGenesis();
3152  MagickWand* wand = NewMagickWand();
3153 
3154  //Write the image located at file_path_name
3155  MagickSetImageColorspace(wand,RGBColorspace);
3156  unsigned long width = (unsigned long)w;
3157  unsigned long height = (unsigned long)h;
3158  MagickConstituteImage(wand,width,height,"RGB",IntegerPixel,(int*)first);
3159  MagickBooleanType status = MagickWriteImage(wand,file_path_name.c_str());
3160  if(status == MagickFalse)
3161  {
3162  ThrowWandException(wand);
3163  }
3164  wand = DestroyMagickWand(wand);
3165  MagickWandTerminus();
3166  }
3167 
3181  template<typename RandomAccessIterator>
3182  inline
3183  void write_magick_color_long(RandomAccessIterator first,
3184  const std::size_t w,
3185  const std::size_t h,
3186  const std::string& file_path_name)
3187  {
3188  //Create the wand
3189  MagickWandGenesis();
3190  MagickWand* wand = NewMagickWand();
3191 
3192  //Write the image located at file_path_name
3193  MagickSetImageColorspace(wand,RGBColorspace);
3194  unsigned long width = (unsigned long)w;
3195  unsigned long height = (unsigned long)h;
3196  MagickConstituteImage(wand,width,height,"RGB",LongPixel,(long*)first);
3197  MagickBooleanType status = MagickWriteImage(wand,file_path_name.c_str());
3198  if(status == MagickFalse)
3199  {
3200  ThrowWandException(wand);
3201  }
3202  wand = DestroyMagickWand(wand);
3203  MagickWandTerminus();
3204  }
3205 
3218  template<typename RandomAccessIterator>
3219  inline
3220  void write_magick_color_float(RandomAccessIterator first,
3221  const std::size_t w,
3222  const std::size_t h,
3223  const std::string& file_path_name)
3224  {
3225  //Create the wand
3226  MagickWandGenesis();
3227  MagickWand* wand = NewMagickWand();
3228 
3229  //Write the image located at file_path_name
3230  MagickSetImageColorspace(wand,RGBColorspace);
3231  unsigned long width = (unsigned long)w;
3232  unsigned long height = (unsigned long)h;
3233  MagickConstituteImage(wand,width,height,"RGB",FloatPixel,(float*)first);
3234  MagickBooleanType status = MagickWriteImage(wand,file_path_name.c_str());
3235  if(status == MagickFalse)
3236  {
3237  ThrowWandException(wand);
3238  }
3239  wand = DestroyMagickWand(wand);
3240  MagickWandTerminus();
3241  }
3242 
3243 
3256  template<typename RandomAccessIterator>
3257  inline
3258  void write_magick_color_double(RandomAccessIterator first,
3259  const std::size_t w,
3260  const std::size_t h,
3261  const std::string& file_path_name)
3262  {
3263  //Create the wand
3264  MagickWandGenesis();
3265  MagickWand* wand = NewMagickWand();
3266 
3267  //Write the image located at file_path_name
3268  MagickSetImageColorspace(wand,RGBColorspace);
3269  unsigned long width = (unsigned long)w;
3270  unsigned long height = (unsigned long)h;
3271  MagickConstituteImage(wand,width,height,"RGB",DoublePixel,(float*)first);
3272  MagickBooleanType status = MagickWriteImage(wand,file_path_name.c_str());
3273  if(status == MagickFalse)
3274  {
3275  ThrowWandException(wand);
3276  }
3277  wand = DestroyMagickWand(wand);
3278  MagickWandTerminus();
3279  }
3280 
3294  template<typename RandomAccessIterator2d>
3295  inline
3296  void write_magick_color(RandomAccessIterator2d upper_left,
3297  RandomAccessIterator2d bottom_right,
3298  const StorageType storage_t,
3299  const std::string& file_path_name)
3300  {
3301 
3302  typename RandomAccessIterator2d::difference_type size2d
3303  = bottom_right - upper_left;
3304 
3305  slip::Array<typename RandomAccessIterator2d::value_type> array(size2d[0] * size2d[1]);
3306  array.fill(upper_left,bottom_right);
3307  if(storage_t == CharPixel)
3308  {
3309  slip::write_magick_color_char(array.begin(),
3310  (std::size_t)size2d[1],
3311  (std::size_t)size2d[0],
3312  file_path_name);
3313 
3314  }
3315  else if(storage_t == ShortPixel)
3316  {
3317  slip::write_magick_color_short(array.begin(),
3318  (std::size_t)size2d[1],
3319  (std::size_t)size2d[0],
3320  file_path_name);
3321  }
3322 
3323  else if(storage_t == IntegerPixel)
3324  {
3325  slip::write_magick_color_int(array.begin(),
3326  (std::size_t)size2d[1],
3327  (std::size_t)size2d[0],
3328  file_path_name);
3329  }
3330  else if(storage_t == LongPixel)
3331  {
3332  slip::write_magick_color_long(array.begin(),
3333  (std::size_t)size2d[1],
3334  (std::size_t)size2d[0],
3335  file_path_name);
3336  }
3337  else if(storage_t == FloatPixel)
3338  {
3339  slip::write_magick_color_float(array.begin(),
3340  (std::size_t)size2d[1],
3341  (std::size_t)size2d[0],
3342  file_path_name);
3343  }
3344  else if(storage_t == DoublePixel)
3345  {
3346  slip::write_magick_color_double(array.begin(),
3347  (std::size_t)size2d[1],
3348  (std::size_t)size2d[0],
3349  file_path_name);
3350  }
3351  else
3352  {
3353  std::cerr<<"Wrong storage type"<<std::endl;
3354  }
3355  }
3356 
3370  template<typename Container2d>
3371  inline
3372  void read_magick_color(const std::string& file_path_name,
3373  Container2d& container,
3374  const StorageType storage_t)
3375  {
3376  //Create the wand
3377  MagickWandGenesis();
3378  MagickWand* wand = NewMagickWand();
3379  //Read the image located at file_path_name
3380  MagickBooleanType status = MagickReadImage(wand,file_path_name.c_str());
3381  if (status == MagickFalse)
3382  {
3383  ThrowWandException(wand);
3384  }
3385  unsigned long width = MagickGetImageWidth(wand);
3386  unsigned long height = MagickGetImageHeight(wand);
3387  container.resize(std::size_t(height),std::size_t(width));
3388 
3389  MagickGetImagePixels(wand,0,0,width,height,"RGB",storage_t,&(container[0][0][0]));
3390  wand = DestroyMagickWand(wand);
3391  }
3392 
3404  template<typename Container2d>
3405  inline
3406  void read_magick_color_char(const std::string& file_path_name,
3407  Container2d& container)
3408  {
3409  read_magick_color(file_path_name,container,CharPixel);
3410  }
3411 
3423  template<typename Container2d>
3424  inline
3425  void read_magick_color_short(const std::string& file_path_name,
3426  Container2d& container)
3427  {
3428  read_magick_color(file_path_name,container,ShortPixel);
3429  }
3430 
3442  template<typename Container2d>
3443  inline
3444  void read_magick_color_int(const std::string& file_path_name,
3445  Container2d& container)
3446  {
3447  read_magick_color(file_path_name,container,IntegerPixel);
3448  }
3449 
3460  template<typename Container2d>
3461  inline
3462  void read_magick_color_long(const std::string& file_path_name,
3463  Container2d& container)
3464  {
3465  read_magick_color(file_path_name,container,LongPixel);
3466  }
3467 
3479  template<typename Container2d>
3480  inline
3481  void read_magick_color_float(const std::string& file_path_name,
3482  Container2d& container)
3483  {
3484  read_magick_color(file_path_name,container,FloatPixel);
3485  }
3486 
3498  template<typename Container2d>
3499  inline
3500  void read_magick_color_double(const std::string& file_path_name,
3501  Container2d& container)
3502  {
3503  read_magick_color(file_path_name,container,DoublePixel);
3504  }
3505 
3506 
3507 /* @} */
3508 #endif //HAVE_MAGICK
3509 
3511  /* @{ */
3529  template <typename Container3d>
3530  inline
3531  void write_tecplot_vol(const Container3d& container,
3532  const std::string& file_path_name,
3533  const std::string& title)
3534  {
3535  std::ofstream output(file_path_name.c_str(),std::ios::out);
3536  try
3537  {
3538  if(!output)
3539  {
3540  throw std::ios_base::failure(slip::FILE_OPEN_ERROR + file_path_name);
3541  }
3542 
3543  int dim1 = int(container.dim1());
3544  int dim2 = int(container.dim2());
3545  int dim3 = int(container.dim3());
3546  //write file informations
3547  output<<"TITLE=\"" <<title<<"\""<<std::endl;
3548  output<<"VARIABLES=\"X\",\"Y\",\"Z\",\"I\"" <<std::endl;
3549  output<<"ZONE T=\"data\" I="<<dim3<<" J="<<dim2<<" K="<<dim1<< " F=POINT"<<std::endl;
3550  //write data
3551  std::size_t dim2_1 = dim2 - 1;
3552  for(int z = 0; z < dim1; ++z)
3553  {
3554  for(int x = 0; x < dim3; ++x)
3555  {
3556  for(int y = 0; y < dim2 ; ++y)
3557  {
3558  output<<x<<" "<<y<<" "<<z<<" "<<container[z][dim2_1-y][x]<<"\n";
3559  }
3560  }
3561  }
3562  output.close();
3563  }
3564  catch(std::exception& e)
3565  {
3566  std::cerr<<e.what()<<std::endl;
3567  output.close();
3568  exit(1);
3569  }
3570  }
3571 
3596  template <typename Container3d>
3597  void write_to_images_tecplot(Container3d& container,
3598  const std::string& file_path_name,
3599  const std::string& title,
3600  const std::size_t from,
3601  const std::size_t to)
3602  {
3603  assert(((to - from) + 1) > 0);
3604  std::ofstream output(file_path_name.c_str(),std::ios::out);
3605  try
3606  {
3607  if(!output)
3608  {
3609  throw std::ios_base::failure(slip::FILE_OPEN_ERROR + file_path_name);
3610  }
3611 
3612  int dim2 = int(container.dim2());
3613  int dim3 = int(container.dim3());
3614  //write file informations
3615  output<<"TITLE=\"" <<title<<"\""<<std::endl;
3616  output<<"VARIABLES=\"X\" \"Y\" \"Z\" \"I\"" <<std::endl;
3617  for(std::size_t img = from; img <= to; ++img)
3618  {
3619  std::string file_name_img = slip::compose_file_name(file_path_name,img);
3620 
3621  output<<"ZONE T=\"image "<<img<<"\" I="<<dim3<<" J="<<dim2<<" F=POINT"<<std::endl;
3622  //write data
3623  std::size_t dim2_1 = dim2 - 1;
3624  for(int x = 0; x < dim3; ++x)
3625  {
3626  for(int y = 0; y < dim2 ; ++y)
3627  {
3628  output<<x<<" "<<y<<" "<<img<<" "<<container[img][dim2_1-y][x]<<"\n";
3629  }
3630  }
3631  }
3632  output.close();
3633  }
3634  catch(std::exception& e)
3635  {
3636  std::cerr<<e.what()<<std::endl;
3637  output.close();
3638  exit(1);
3639  }
3640 
3641  }
3642 #ifdef HAVE_MAGICK
3643 
3680  template <typename RandomAccessIterator>
3681  void write_to_images(const std::string& file_path_name,
3682  const std::size_t from,
3683  const std::size_t to,
3684  const std::size_t w,
3685  const std::size_t h,
3686  const StorageType storage_t,
3687  RandomAccessIterator plane_begin)
3688  {
3689  assert(((to - from) + 1) > 0);
3690  for(std::size_t img = from; img <= to; ++img)
3691  {
3692  std::string file_name_img = slip::compose_file_name(file_path_name,img);
3693  slip::write_magick_gray(plane_begin[img-from],w,h,storage_t,file_name_img);
3694  }
3695  }
3696 
3715  template <typename RandomAccessIterator>
3716  void write_to_images_char(const std::string& file_path_name,
3717  const std::size_t from,
3718  const std::size_t to,
3719  const std::size_t w,
3720  const std::size_t h,
3721  RandomAccessIterator plane_begin)
3722  {
3723  slip::write_to_images(file_path_name,from,to,w,h,CharPixel,plane_begin);
3724  }
3725 
3744  template <typename RandomAccessIterator>
3745  void write_to_images_short(const std::string& file_path_name,
3746  const std::size_t from,
3747  const std::size_t to,
3748  const std::size_t w,
3749  const std::size_t h,
3750  RandomAccessIterator plane_begin)
3751  {
3752  slip::write_to_images(file_path_name,from,to,w,h,ShortPixel,plane_begin);
3753  }
3754 
3773  template <typename RandomAccessIterator>
3774  void write_to_images_int(const std::string& file_path_name,
3775  const std::size_t from,
3776  const std::size_t to,
3777  const std::size_t w,
3778  const std::size_t h,
3779  RandomAccessIterator plane_begin)
3780  {
3781  slip::write_to_images(file_path_name,from,to,w,h,IntegerPixel,plane_begin);
3782  }
3783 
3802  template <typename RandomAccessIterator>
3803  void write_to_images_long(const std::string& file_path_name,
3804  const std::size_t from,
3805  const std::size_t to,
3806  const std::size_t w,
3807  const std::size_t h,
3808  RandomAccessIterator plane_begin)
3809  {
3810  slip::write_to_images(file_path_name,from,to,w,h,LongPixel,plane_begin);
3811  }
3812 
3831  template <typename RandomAccessIterator>
3832  void write_to_images_float(const std::string& file_path_name,
3833  const std::size_t from,
3834  const std::size_t to,
3835  const std::size_t w,
3836  const std::size_t h,
3837  RandomAccessIterator plane_begin)
3838  {
3839  slip::write_to_images(file_path_name,from,to,w,h,FloatPixel,plane_begin);
3840  }
3841 
3842 
3861  template <typename RandomAccessIterator>
3862  void write_to_images_double(const std::string& file_path_name,
3863  const std::size_t from,
3864  const std::size_t to,
3865  const std::size_t w,
3866  const std::size_t h,
3867  RandomAccessIterator plane_begin)
3868  {
3869  slip::write_to_images(file_path_name,from,to,w,h,DoublePixel,plane_begin);
3870  }
3871 
3872 
3908  template<typename Container3d>
3909  inline
3910  void read_from_images(const std::string& file_path_name,
3911  const std::size_t from,
3912  const std::size_t to,
3913  Container3d& container,
3914  const StorageType storage_t)
3915  {
3916  assert(((to - from) + 1) > 0);
3917 
3918  std::ifstream input;
3919  try
3920  {
3921  //read first slice
3922  std::string file_name_img = slip::compose_file_name(file_path_name,from);
3923  input.open(file_name_img.c_str(),std::ios::in);
3924  if (!input)
3925  {
3926  throw std::ios_base::failure(slip::FILE_OPEN_ERROR + file_path_name);
3927  }
3929  read_magick_gray(file_name_img,Mat,storage_t);
3930  //resize the container
3931  container.resize((to-from) + 1,Mat.dim1(),Mat.dim2(),0);
3932  //copy the first slice
3933  std::copy(Mat.begin(),Mat.end(),container.plane_begin(0));
3934  input.close();
3935 
3936  for(std::size_t img = (from + 1); img <= to; ++img)
3937  {
3938  file_name_img = slip::compose_file_name(file_path_name,img);
3939  input.open(file_name_img.c_str(),std::ios::in);
3940  if (!input)
3941  {
3942  throw std::ios_base::failure(slip::FILE_OPEN_ERROR + file_name_img);
3943  }
3945  read_magick_gray(file_name_img,Mat,storage_t);
3946  assert(Mat.dim1() == container.dim2());
3947  assert(Mat.dim2() == container.dim3());
3948  std::copy(Mat.begin(),Mat.end(),container.plane_begin(img-from));
3949  input.close();
3950  }
3951  }
3952  catch(std::exception& e)
3953  {
3954  std::cerr<<e.what()<<std::endl;
3955  input.close();
3956  exit(1);
3957  }
3958  }
3959 
3975  template<typename Container3d>
3976  inline
3977  void read_from_images_char(const std::string& file_path_name,
3978  const std::size_t from,
3979  const std::size_t to,
3980  Container3d& container)
3981  {
3982  slip::read_from_images(file_path_name,from,to,container,CharPixel);
3983  }
3984 
3985 
4001  template<typename Container3d>
4002  inline
4003  void read_from_images_int(const std::string& file_path_name,
4004  const std::size_t from,
4005  const std::size_t to,
4006  Container3d& container)
4007  {
4008  slip::read_from_images(file_path_name,from,to,container,IntegerPixel);
4009  }
4010 
4025  template<typename Container3d>
4026  inline
4027  void read_from_images_short(const std::string& file_path_name,
4028  const std::size_t from,
4029  const std::size_t to,
4030  Container3d& container)
4031  {
4032  slip::read_from_images(file_path_name,from,to,container,ShortPixel);
4033  }
4034 
4050  template<typename Container3d>
4051  inline
4052  void read_from_images_long(const std::string& file_path_name,
4053  const std::size_t from,
4054  const std::size_t to,
4055  Container3d& container)
4056  {
4057  slip::read_from_images(file_path_name,from,to,container,LongPixel);
4058  }
4059 
4075  template<typename Container3d>
4076  inline
4077  void read_from_images_float(const std::string& file_path_name,
4078  const std::size_t from,
4079  const std::size_t to,
4080  Container3d& container)
4081  {
4082  slip::read_from_images(file_path_name,from,to,container,FloatPixel);
4083  }
4084 
4100  template<typename Container3d>
4101  inline
4102  void read_from_images_double(const std::string& file_path_name,
4103  const std::size_t from,
4104  const std::size_t to,
4105  Container3d& container)
4106  {
4107  slip::read_from_images(file_path_name,from,to,container,DoublePixel);
4108  }
4109  #endif //HAVE_MAGICK
4110 /* @} */
4111 
4112 }//::slip
4113 
4114 #endif //SLIP_IO_TOOLS_HPP
void write_tecplot_2d(RandomAccessIterator2d upper_left, RandomAccessIterator2d bottom_right, const std::string &file_path_name, const std::string &title, const std::string &zone, const int precision=6)
Write a Container2d to an ASCII file.
Definition: io_tools.hpp:702
void read_tecplot_vect2d(const std::string &file_path_name, MultiContainer2d &field)
Create a DenseVector2dField2D from a tecplot file.
Definition: io_tools.hpp:1080
Provides a class to modelize 3d points.
void read_ascii_1d(const std::string &file_path_name, Container1d &container)
Read a Container1d from an ASCII file.
Definition: io_tools.hpp:2518
size_type dim1() const
Returns the number of rows (first dimension size) in the Matrix.
Definition: Matrix.hpp:3495
void write_tecplot_vol(const Container3d &container, const std::string &file_path_name, const std::string &title)
Write a Container3D to a tecplot file.
Definition: io_tools.hpp:3531
size_type dim3() const
Returns the number of columns (third dimension size) in the GenericMultiComponent3d.
T & min(const GrayscaleImage< T > &M1)
Returns the min element of a GrayscaleImage.
iterator begin()
Returns a read/write iterator that points to the first element in the Matrix. Iteration is done in or...
Definition: Matrix.hpp:2789
size_type dim2() const
Returns the number of rows (second dimension size) in the GenericMultiComponent3d.
void write_gnuplot_vect2d(const MultiContainer2d &field, const std::string &file_path_name, const int precision=6)
Write a DenseVector2dField2D to a gnuplot file.
Definition: io_tools.hpp:777
void read_gnuplot_vect2d(const std::string &file_path_name, MultiContainer2d &field)
Create a DenseVector2dField2D from a gnuplot file.
Definition: io_tools.hpp:1521
HyperVolume< T > abs(const HyperVolume< T > &M)
Provides a class to manipulate 1d dynamic and generic arrays.
This is a point2d class, a specialized version of Point<CoordType,DIM> with DIM = 2...
Definition: Array2d.hpp:132
void print(const Container &C, const std::string &name="")
Print the name of the container follow by the values of the container in a terminal.
Definition: io_tools.hpp:246
const std::string FILE_OPEN_ERROR
Definition: error.hpp:82
void write_to_images_tecplot(Container3d &container, const std::string &file_path_name, const std::string &title, const std::size_t from, const std::size_t to)
Write slices of a Container3D to a tecplot file.
Definition: io_tools.hpp:3597
void read_tecplot_vect3d(const std::string &file_path_name, MultiContainer3d &field)
Create a DenseVector3dField3D from a tecplot file.
Definition: io_tools.hpp:1860
void write_ascii_1d(InputIterator first, InputIterator last, const std::string &file_path_name)
Write a Container1d to an ASCII file.
Definition: io_tools.hpp:2475
void write_tecplot_vect3d(const DenseVector3dField3d &field, const std::string &file_path_name, const std::string &title, const std::string &zone, const int precision=6)
Write a DenseVector3dField3D to a tecplot file.
Definition: io_tools.hpp:1685
std::size_t split_extension(const std::string &file_path_name, std::string &file_path_name_cut, std::string &ext)
Split a file_name in two substrings: the file_path_name string without the extension and the extensio...
Definition: io_tools.hpp:159
void copy(_II first, _II last, _OI output_first)
Copy algorithm optimized for slip iterators.
Definition: copy_ext.hpp:177
size_type rows() const
Returns the number of rows (first dimension size) in the Array2d.
Definition: Array2d.hpp:3139
col_iterator col_begin(const size_type col)
Returns a read/write iterator that points to the first element of the column column in the Array2d...
void read_gnuplot_XYZ(const std::string &file_path_name, MultiContainer3d &XYZ)
Create a XYZ DenseVector3dField3D from a gnuplot file.
Definition: io_tools.hpp:2437
Numerical matrix class. This container statisfies the BidirectionnalContainer concepts of the STL...
Provides SLIP error messages.
std::string compose_file_name(const std::string &file_path_name, const std::size_t img)
Compose a file_name from the file name format basenamend*.ext.
Definition: io_tools.hpp:203
void write_tecplot_vect2d(const MultiContainer2d &field, const std::string &file_path_name, const std::string &title, const std::string &zone, const int precision=6)
Write a DenseVector2dField2D to a tecplot file.
Definition: io_tools.hpp:914
void read_tecplot_XY(const std::string &file_path_name, MultiContainer2d &XY)
Create a XY DenseVector2dField2D from a tecplot file.
Definition: io_tools.hpp:1312
This is a Dense Vector3d Field. This container statisfies the BidirectionnalContainer concepts of the...
void read_gnuplot_XY(const std::string &file_path_name, MultiContainer2d &XY)
Create a XY DenseVector2dField2D from a gnuplot file.
Definition: io_tools.hpp:1604
iterator end()
Returns a read/write iterator that points one past the last element in the Matrix. Iteration is done in ordinary element order.
Definition: Matrix.hpp:2796
col_iterator col_end(const size_type col)
Returns a read/write iterator that points one past the end element of the column column in the Array2...
Provides a class to manipulate Numerical Matrix.
Provides a class to modelize 2d points.
Provides a class to iterate a 1d range according to a step.
size_type dim2() const
Returns the number of columns (second dimension size) in the Matrix.
Definition: Matrix.hpp:3504
void read_ascii_2d(Container2d &container, const std::string &file_path_name)
Read a Container2d from an ASCII file.
Definition: io_tools.hpp:544
This is a linear (one-dimensional) dynamic template container. This container statisfies the RandomAc...
Definition: Array.hpp:94
void write_raw(InputIterator first, InputIterator last, const std::string &file_path_name)
Write a Container to an raw file.
Definition: io_tools.hpp:290
void read_tecplot_XYZ(const std::string &file_path_name, MultiContainer3d &XYZ)
Create a XYZ DenseVector3dField3D from a tecplot file.
Definition: io_tools.hpp:2153
This is a two-dimensional dynamic and generic container. This container statisfies the Bidirectionnal...
Definition: Array2d.hpp:135
This is a point3d class, a specialized version of Point<CoordType,DIM> with DIM = 3...
void write_ascii_2d(RandomAccessIterator2d upper_left, RandomAccessIterator2d bottom_right, const std::string &file_path_name)
Write a Container2d to an ASCII file.
Definition: io_tools.hpp:408
size_type dim1() const
Returns the number of slices (first dimension size) in the GenericMultiComponent3d.
void read_raw(const std::string &file_path_name, InputIterator first, InputIterator last)
Write a Container to an raw file.
Definition: io_tools.hpp:345