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