]> Creatis software - clitk.git/blob - common/clitkCommon.cxx
Add windows maths include
[clitk.git] / common / clitkCommon.cxx
1 /*=========================================================================
2   Program:   vv                     http://www.creatis.insa-lyon.fr/rio/vv
3
4   Authors belong to:
5   - University of LYON              http://www.universite-lyon.fr/
6   - Léon Bérard cancer center       http://www.centreleonberard.fr
7   - CREATIS CNRS laboratory         http://www.creatis.insa-lyon.fr
8
9   This software is distributed WITHOUT ANY WARRANTY; without even
10   the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
11   PURPOSE.  See the copyright notices for more information.
12
13   It is distributed under dual licence
14
15   - BSD        See included LICENSE.txt file
16   - CeCILL-B   http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
17 ===========================================================================**/
18
19 #ifndef CLITKCOMMON_CXX
20 #define CLITKCOMMON_CXX
21
22 #include <itksys/SystemTools.hxx>
23
24 #ifndef _WIN32
25   #define _USE_MATH_DEFINES
26   #include <cmath>
27 #endif
28
29 // clitk include 
30 #include "clitkCommon.h"
31
32 // std include 
33 #include <fstream>
34 #include <iomanip>
35 #include <sstream>
36 #include <cerrno>
37
38 //------------------------------------------------------------------
39 // skip line which begin with a sharp '#'
40 void clitk::skipComment(std::istream & is)
41 {
42   char c;
43   char line[1024];
44   if (is.eof()) return;
45   is >> c ;
46   while (is && (c == '#')) {
47     is.getline (line, 1024);
48     is >> c;
49     if (is.eof()) return;
50   }
51   if (!(is.fail()) && c != '\n')
52     is.unget();
53 } ////
54 //------------------------------------------------------------------
55
56 //------------------------------------------------------------------
57 // linear (rough) conversion from Hounsfield Unit to density
58 double clitk::HU2density(double HU)
59 {
60   return (HU+1000.0)/1000.0;
61 } ////
62 //------------------------------------------------------------------
63
64 //------------------------------------------------------------------
65 // Return filename extension
66 std::string clitk::GetExtension(const std::string& filename)
67 {
68   // This assumes that the final '.' in a file name is the delimiter
69   // for the file's extension type
70   const std::string::size_type it = filename.find_last_of( "." );
71   // This determines the file's type by creating a new string
72   // who's value is the extension of the input filename
73   // eg. "myimage.gif" has an extension of "gif"
74   std::string fileExt( filename, it+1, filename.length() );
75   return( fileExt );
76 } ////
77 //------------------------------------------------------------------
78
79
80 //------------------------------------------------------------------
81 // Return filename splitting in 1 or 2 parts : directory name (if exists) & filename
82 std::vector<std::string> clitk::SplitFilename(const std::string& filename)
83 {
84   std::vector<std::string> dirname;
85   std::string path = itksys::SystemTools::GetFilenamePath(filename);
86   std::vector<std::string> pathComponents;
87   itksys::SystemTools::SplitPath(filename.c_str(), pathComponents);
88   std::string fileName = pathComponents.back();
89   if (path != "")
90     dirname.push_back(path);
91   dirname.push_back(fileName);
92   return( dirname );
93 } ////
94 //------------------------------------------------------------------
95
96
97 //------------------------------------------------------------------
98 // Display progression
99 void clitk::VerboseInProgress(const int nb, const int current, const int percentage)
100 {
101   static int previous = -1;
102   const int rounded = (100*current)/nb;
103   if (previous==rounded) return;
104   previous = rounded;
105
106   std::ostringstream oss;
107   oss << std::setw(4) << rounded << '%';
108
109   std::cout << oss.str() << std::flush;
110   for (unsigned int i=0; i<oss.str().length(); ++i)
111     std::cout << "\b" << std::flush;
112 }
113 //------------------------------------------------------------------
114
115 //------------------------------------------------------------------
116 // Display progression
117 void clitk::VerboseInProgressInPercentage(const int nb, const int current, const int percentage)
118 {
119   VerboseInProgress(nb, current, percentage);
120 }
121 //------------------------------------------------------------------
122
123 //------------------------------------------------------------------
124 // Convert a pixel type to another (downcast)
125 template<>
126 float clitk::PixelTypeDownCast(const double & x)
127 {
128   return (float)x;
129 }
130 //------------------------------------------------------------------
131
132 //------------------------------------------------------------------
133 // Convert a pixel type without casting
134 template<>
135 double clitk::PixelTypeDownCast(const double & x)
136 {
137   return x;
138 }
139 //------------------------------------------------------------------
140
141 //------------------------------------------------------------------
142 double clitk::rad2deg(const double anglerad)
143 {
144   return (anglerad/M_PI*180.0);
145 }
146 //------------------------------------------------------------------
147
148 //------------------------------------------------------------------
149 double clitk::deg2rad(const double angledeg)
150 {
151   return (angledeg*(M_PI/180.0));
152 }
153 //------------------------------------------------------------------
154
155 //------------------------------------------------------------------
156 int clitk::GetTypeSizeFromString(const std::string & type)
157 {
158 #define RETURN_SIZEOF_PIXEL(TYPENAME, TYPE)             \
159   if (type == #TYPENAME) return sizeof(TYPE);
160   RETURN_SIZEOF_PIXEL(char, char);
161   RETURN_SIZEOF_PIXEL(uchar, uchar);
162   RETURN_SIZEOF_PIXEL(unsigned char, uchar);
163   RETURN_SIZEOF_PIXEL(unsigned_char, uchar);
164   RETURN_SIZEOF_PIXEL(short, short);
165   RETURN_SIZEOF_PIXEL(ushort, ushort);
166   RETURN_SIZEOF_PIXEL(unsigned_short, ushort);
167   RETURN_SIZEOF_PIXEL(int, int);
168   RETURN_SIZEOF_PIXEL(uint, uint);
169   RETURN_SIZEOF_PIXEL(unsigned_int, uint);
170   RETURN_SIZEOF_PIXEL(float, float);
171   RETURN_SIZEOF_PIXEL(double, double);
172   return 0;
173 }
174 //------------------------------------------------------------------
175
176 //------------------------------------------------------------------
177 template<>
178 bool clitk::IsSameType<signed char>(std::string t)
179 {
180   if ((t==GetTypeAsString<signed char>()) || (t == "schar")) return true;
181   else return false;
182 }
183
184 template<>
185 bool clitk::IsSameType<char>(std::string t)
186 {
187   if ((t==GetTypeAsString<char>()) || (t == "char")) return true;
188   else return false;
189 }
190
191 template<>
192 bool clitk::IsSameType<unsigned char>(std::string t)
193 {
194   if ((t==GetTypeAsString<unsigned char>()) || (t == "uchar")) return true;
195   else return false;
196 }
197
198 template<>
199 bool clitk::IsSameType<unsigned short>(std::string t)
200 {
201   if ((t==GetTypeAsString<unsigned short>()) || (t == "ushort")) return true;
202   else return false;
203 }
204 //------------------------------------------------------------------
205
206 //------------------------------------------------------------------
207 void clitk::FindAndReplace(std::string & line,
208                            const std::string & tofind,
209                            const std::string & replacement)
210 {
211   int pos = line.find(tofind);
212   while (pos!= (int)std::string::npos) {
213     line.replace(pos, tofind.size(), replacement);
214     pos = line.find(tofind, pos+tofind.size()+1);
215   }
216 }
217 //------------------------------------------------------------------
218
219 //------------------------------------------------------------------
220 void clitk::FindAndReplace(std::string & line,
221                            const std::vector<std::string> & tofind,
222                            const std::vector<std::string> & toreplace)
223 {
224   for(unsigned int i=0; i<tofind.size(); i++) {
225     FindAndReplace(line, tofind[i], toreplace[i]);
226   }
227 }
228 //------------------------------------------------------------------
229
230 //------------------------------------------------------------------
231 void clitk::FindAndReplace(std::ifstream & in,
232                            const std::vector<std::string> & tofind,
233                            const std::vector<std::string> & toreplace,
234                            std::ofstream & out)
235 {
236   std::string line;
237   if (tofind.size() != toreplace.size()) {
238     std::cerr << "Error' tofind' is size=" << tofind.size() << std::endl;
239     std::cerr << "... while 'toreplace' is size=" << toreplace.size() << std::endl;
240     exit(0);
241   }
242   while (std::getline(in,line)) {
243     FindAndReplace(line, tofind, toreplace);
244     out << line << std::endl;
245   }
246 }
247 //------------------------------------------------------------------
248
249 //------------------------------------------------------------------
250 double clitk::ComputeEuclideanDistanceFromPointToPlane(const itk::ContinuousIndex<double, 3> point,
251     const itk::ContinuousIndex<double, 3> pointInPlane,
252     const itk::ContinuousIndex<double, 3> normalPlane)
253 {
254   // http://mathworld.wolfram.com/Plane.html
255   // http://mathworld.wolfram.com/Point-PlaneDistance.html
256   double a = normalPlane[0];
257   double b = normalPlane[1];
258   double c = normalPlane[2];
259   double x0 = pointInPlane[0];
260   double y0 = pointInPlane[1];
261   double z0 = pointInPlane[2];
262   double x = point[0];
263   double y = point[1];
264   double z = point[2];
265
266   double norm = sqrt(x0*x0 + y0*y0 + z0*z0);
267   DD(norm);
268   double d = -a*x0 - b*y0 - c*z0;
269   DD(d);
270   double distance = (a*x + b*y + c*z + d) / norm;
271
272   return distance;
273 }
274 //------------------------------------------------------------------
275
276 //--------------------------------------------------------------------
277 // Open a file for reading
278 void clitk::openFileForReading(std::ifstream & is, const std::string & filename)
279 {
280   is.open(filename.c_str(), std::ios::in | std::ios::binary);
281   if ( is.fail() ) {
282     clitkExceptionMacro("Could not open file for reading: " 
283                         << filename << ". Error is : <" 
284                         << strerror(errno) << ">");
285   }
286 }
287 //--------------------------------------------------------------------
288
289 //--------------------------------------------------------------------
290 // Open a file for writing
291 void clitk::openFileForWriting(std::ofstream & os, const std::string & filename)
292 {
293   os.open(filename.c_str(), std::ios::out);
294   if ( os.fail() ) {
295     clitkExceptionMacro("Could not open file for writing: " 
296                         << filename << ". Error is : <" 
297                         << strerror(errno) << ">");
298   }
299 }
300 //--------------------------------------------------------------------
301
302 //--------------------------------------------------------------------
303 double clitk::cotan(double i)
304 {
305   return(1.0 / tan(i));
306 }
307 double clitk::invcotan(double x)
308 {
309   //  http://mathworld.wolfram.com/InverseCotangent.html
310   double y;
311   if (x<0) {
312     y = -0.5*M_PI-atan(x);
313   } else {
314     y = 0.5*M_PI-atan(x);
315   }
316   return y;
317 }
318 //--------------------------------------------------------------------
319
320 //--------------------------------------------------------------------
321 std::streambuf * clitk_stdcerr_backup;
322 void clitk::disableStdCerr()
323 {
324   clitk_stdcerr_backup = std::cerr.rdbuf();
325   std::stringstream oss;
326   std::cerr.rdbuf( oss.rdbuf() );
327 }
328 //--------------------------------------------------------------------
329
330 //--------------------------------------------------------------------
331 void clitk::enableStdCerr()
332 {
333   std::cerr.rdbuf(clitk_stdcerr_backup);
334 }
335 //--------------------------------------------------------------------
336
337
338 //--------------------------------------------------------------------
339 void clitk::readDoubleFromFile(const std::string & filename, std::vector<double> & list)
340 {
341   std::ifstream is;
342   clitk::openFileForReading(is, filename);
343   list.clear();
344   while (is) {
345     clitk::skipComment(is);
346     double d;
347     is >> d;
348     if (is) list.push_back(d);
349   }
350 }
351 //--------------------------------------------------------------------
352
353
354 //--------------------------------------------------------------------
355 void clitk::PrintMemoryUsed()
356 {
357 #if defined(unix) || defined(__APPLE__)
358   rusage usage;  
359   getrusage(RUSAGE_SELF, &usage);
360   DD(usage.ru_maxrss);        /* maximum resident set size */ 
361   // DD(usage.ru_ixrss);         /* integral shared memory size */
362   // DD(usage.ru_idrss);         /* integral unshared data size */
363   // DD(usage.ru_isrss);         /* integral unshared stack size */
364 #endif
365 }
366 //--------------------------------------------------------------------
367
368
369 #endif /* end #define CLITKCOMMON_CXX */
370